JVM IR: slightly cleanup and split IrUtils.kt
- Move IrType-specific utilities to separate JvmIrTypeUtils.kt - Extract JvmIrBuilder to a separate file - Rename IrUtils.kt to JvmIrUtils.kt to be able to tell it apart from numerous other IR utils files
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jvm.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
|
||||
// An IR builder with a reference to the JvmBackendContext
|
||||
class JvmIrBuilder(
|
||||
val backendContext: JvmBackendContext,
|
||||
val symbol: IrSymbol,
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET,
|
||||
) : IrBuilderWithScope(
|
||||
IrGeneratorContextBase(backendContext.irBuiltIns),
|
||||
Scope(symbol),
|
||||
startOffset,
|
||||
endOffset
|
||||
) {
|
||||
val irSymbols: JvmSymbols
|
||||
get() = backendContext.ir.symbols
|
||||
}
|
||||
|
||||
fun JvmBackendContext.createJvmIrBuilder(
|
||||
symbol: IrSymbol,
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET,
|
||||
): JvmIrBuilder = JvmIrBuilder(this, symbol, startOffset, endOffset)
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jvm.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.representativeUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrScript
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
|
||||
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.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.isLocal
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
|
||||
/**
|
||||
* Perform as much type erasure as is significant for JVM signature generation.
|
||||
* Class types are kept as is, while type parameters are replaced with their
|
||||
* erased upper bounds, keeping the nullability information.
|
||||
*
|
||||
* For example, a type parameter `T?` where `T : Any`, `T : Comparable<T>` is
|
||||
* erased to `Any?`.
|
||||
*
|
||||
* Type arguments to the erased upper bound are replaced by `*`, since
|
||||
* recursive erasure could loop. For example, a type parameter
|
||||
* `T : Comparable<T>` is replaced by `Comparable<*>`.
|
||||
*/
|
||||
fun IrType.eraseTypeParameters(): IrType = when (this) {
|
||||
is IrErrorType -> this
|
||||
is IrSimpleType ->
|
||||
when (val owner = classifier.owner) {
|
||||
is IrScript -> {
|
||||
assert(arguments.isEmpty()) { "Script can't be generic: " + owner.render() }
|
||||
IrSimpleTypeImpl(classifier, hasQuestionMark, emptyList(), annotations)
|
||||
}
|
||||
is IrClass -> IrSimpleTypeImpl(classifier, hasQuestionMark, arguments.map { it.eraseTypeParameters() }, annotations)
|
||||
is IrTypeParameter -> {
|
||||
val upperBound = owner.erasedUpperBound
|
||||
IrSimpleTypeImpl(
|
||||
upperBound.symbol,
|
||||
isNullable(),
|
||||
// Should not affect JVM signature, but may result in an invalid type object
|
||||
List(upperBound.typeParameters.size) { IrStarProjectionImpl },
|
||||
owner.annotations
|
||||
)
|
||||
}
|
||||
else -> error("Unknown IrSimpleType classifier kind: $owner")
|
||||
}
|
||||
else -> error("Unknown IrType kind: $this")
|
||||
}
|
||||
|
||||
private fun IrTypeArgument.eraseTypeParameters(): IrTypeArgument = when (this) {
|
||||
is IrStarProjection -> this
|
||||
is IrTypeProjection -> makeTypeProjection(type.eraseTypeParameters(), variance)
|
||||
else -> error("Unknown IrTypeArgument kind: $this")
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the erased class for this type parameter according to the java erasure rules.
|
||||
*/
|
||||
val IrTypeParameter.erasedUpperBound: IrClass
|
||||
get() {
|
||||
// Pick the (necessarily unique) non-interface upper bound if it exists
|
||||
for (type in superTypes) {
|
||||
val irClass = type.classOrNull?.owner ?: continue
|
||||
if (!irClass.isJvmInterface) return irClass
|
||||
}
|
||||
|
||||
// Otherwise, choose either the first IrClass supertype or recurse.
|
||||
// In the first case, all supertypes are interface types and the choice was arbitrary.
|
||||
// In the second case, there is only a single supertype.
|
||||
return superTypes.first().erasedUpperBound
|
||||
}
|
||||
|
||||
val IrType.erasedUpperBound: IrClass
|
||||
get() = when (val classifier = classifierOrNull) {
|
||||
is IrClassSymbol -> classifier.owner
|
||||
is IrTypeParameterSymbol -> classifier.owner.erasedUpperBound
|
||||
is IrScriptSymbol -> classifier.owner.targetClass!!.owner
|
||||
else -> error(render())
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default null/0 value for the type.
|
||||
*
|
||||
* This handles unboxing of non-nullable inline class types to their underlying types and produces
|
||||
* a null/0 default value for the resulting type. When such unboxing takes place it ensures that
|
||||
* the value is not reboxed and reunboxed by the codegen by using the unsafeCoerceIntrinsic.
|
||||
*/
|
||||
fun IrType.defaultValue(startOffset: Int, endOffset: Int, context: JvmBackendContext): IrExpression {
|
||||
val classifier = this.classifierOrNull
|
||||
if (classifier is IrTypeParameterSymbol) {
|
||||
return classifier.owner.representativeUpperBound.defaultValue(startOffset, endOffset, context)
|
||||
}
|
||||
|
||||
if (this !is IrSimpleType || hasQuestionMark || classOrNull?.owner?.isInline != true)
|
||||
return IrConstImpl.defaultValueForType(startOffset, endOffset, this)
|
||||
|
||||
val underlyingType = unboxInlineClass()
|
||||
val defaultValueForUnderlyingType = IrConstImpl.defaultValueForType(startOffset, endOffset, underlyingType)
|
||||
return IrCallImpl.fromSymbolOwner(startOffset, endOffset, this, context.ir.symbols.unsafeCoerceIntrinsic).also {
|
||||
it.putTypeArgument(0, underlyingType) // from
|
||||
it.putTypeArgument(1, this) // to
|
||||
it.putValueArgument(0, defaultValueForUnderlyingType)
|
||||
}
|
||||
}
|
||||
|
||||
fun IrType.isInlineClassType(): Boolean =
|
||||
erasedUpperBound.isInline
|
||||
|
||||
val IrType.upperBound: IrType
|
||||
get() = erasedUpperBound.symbol.starProjectedType
|
||||
|
||||
fun IrType.eraseToScope(scopeOwner: IrTypeParametersContainer): IrType =
|
||||
eraseToScope(collectVisibleTypeParameters(scopeOwner))
|
||||
|
||||
fun IrType.eraseToScope(visibleTypeParameters: Set<IrTypeParameter>): IrType {
|
||||
require(this is IrSimpleType) { error("Unexpected IrType kind: ${render()}") }
|
||||
return when (classifier) {
|
||||
is IrClassSymbol -> IrSimpleTypeImpl(
|
||||
classifier, hasQuestionMark, arguments.map { it.eraseToScope(visibleTypeParameters) }, annotations
|
||||
)
|
||||
is IrTypeParameterSymbol -> if (classifier.owner in visibleTypeParameters) this else upperBound
|
||||
else -> error("unknown IrType classifier kind: ${classifier.owner.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrTypeArgument.eraseToScope(visibleTypeParameters: Set<IrTypeParameter>): IrTypeArgument = when (this) {
|
||||
is IrStarProjection -> this
|
||||
is IrTypeProjection -> makeTypeProjection(type.eraseToScope(visibleTypeParameters), variance)
|
||||
else -> error("unknown type projection kind: ${render()}")
|
||||
}
|
||||
|
||||
fun collectVisibleTypeParameters(scopeOwner: IrTypeParametersContainer): Set<IrTypeParameter> =
|
||||
generateSequence(scopeOwner) { current ->
|
||||
val parent = current.parent as? IrTypeParametersContainer
|
||||
parent.takeUnless { parent is IrClass && current is IrClass && !current.isInner && !current.isLocal }
|
||||
}
|
||||
.flatMap { it.typeParameters }
|
||||
.toSet()
|
||||
+3
-160
@@ -9,11 +9,8 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.backend.jvm.CachedFieldsForObjectInstances
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmSymbols
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineOnly
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.representativeUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
@@ -24,23 +21,17 @@ import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOT
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.PsiIrFileEntry
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContextBase
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
@@ -54,97 +45,6 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
/**
|
||||
* Perform as much type erasure as is significant for JVM signature generation.
|
||||
* Class types are kept as is, while type parameters are replaced with their
|
||||
* erased upper bounds, keeping the nullability information.
|
||||
*
|
||||
* For example, a type parameter `T?` where `T : Any`, `T : Comparable<T>` is
|
||||
* erased to `Any?`.
|
||||
*
|
||||
* Type arguments to the erased upper bound are replaced by `*`, since
|
||||
* recursive erasure could loop. For example, a type parameter
|
||||
* `T : Comparable<T>` is replaced by `Comparable<*>`.
|
||||
*/
|
||||
fun IrType.eraseTypeParameters() = when (this) {
|
||||
is IrErrorType -> this
|
||||
is IrSimpleType ->
|
||||
when (val owner = classifier.owner) {
|
||||
is IrScript -> {
|
||||
assert(arguments.isEmpty()) { "Script can't be generic: " + owner.render() }
|
||||
IrSimpleTypeImpl(classifier, hasQuestionMark, emptyList(), annotations)
|
||||
}
|
||||
is IrClass -> IrSimpleTypeImpl(classifier, hasQuestionMark, arguments.map { it.eraseTypeParameters() }, annotations)
|
||||
is IrTypeParameter -> {
|
||||
val upperBound = owner.erasedUpperBound
|
||||
IrSimpleTypeImpl(
|
||||
upperBound.symbol,
|
||||
isNullable(),
|
||||
List(upperBound.typeParameters.size) { IrStarProjectionImpl }, // Should not affect JVM signature, but may result in an invalid type object
|
||||
owner.annotations
|
||||
)
|
||||
}
|
||||
else -> error("Unknown IrSimpleType classifier kind: $owner")
|
||||
}
|
||||
else -> error("Unknown IrType kind: $this")
|
||||
}
|
||||
|
||||
private fun IrTypeArgument.eraseTypeParameters(): IrTypeArgument = when (this) {
|
||||
is IrStarProjection -> this
|
||||
is IrTypeProjection -> makeTypeProjection(type.eraseTypeParameters(), variance)
|
||||
else -> error("Unknown IrTypeArgument kind: $this")
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the erased class for this type parameter according to the java erasure rules.
|
||||
*/
|
||||
val IrTypeParameter.erasedUpperBound: IrClass
|
||||
get() {
|
||||
// Pick the (necessarily unique) non-interface upper bound if it exists
|
||||
for (type in superTypes) {
|
||||
val irClass = type.classOrNull?.owner ?: continue
|
||||
if (!irClass.isJvmInterface) return irClass
|
||||
}
|
||||
|
||||
// Otherwise, choose either the first IrClass supertype or recurse.
|
||||
// In the first case, all supertypes are interface types and the choice was arbitrary.
|
||||
// In the second case, there is only a single supertype.
|
||||
return superTypes.first().erasedUpperBound
|
||||
}
|
||||
|
||||
val IrType.erasedUpperBound: IrClass
|
||||
get() = when (val classifier = classifierOrNull) {
|
||||
is IrClassSymbol -> classifier.owner
|
||||
is IrTypeParameterSymbol -> classifier.owner.erasedUpperBound
|
||||
is IrScriptSymbol -> classifier.owner.targetClass!!.owner
|
||||
else -> error(render())
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default null/0 value for the type.
|
||||
*
|
||||
* This handles unboxing of non-nullable inline class types to their underlying types and produces
|
||||
* a null/0 default value for the resulting type. When such unboxing takes place it ensures that
|
||||
* the value is not reboxed and reunboxed by the codegen by using the unsafeCoerceIntrinsic.
|
||||
*/
|
||||
fun IrType.defaultValue(startOffset: Int, endOffset: Int, context: JvmBackendContext): IrExpression {
|
||||
val classifier = this.classifierOrNull
|
||||
if (classifier is IrTypeParameterSymbol) {
|
||||
return classifier.owner.representativeUpperBound.defaultValue(startOffset, endOffset, context)
|
||||
}
|
||||
|
||||
if (this !is IrSimpleType || hasQuestionMark || classOrNull?.owner?.isInline != true)
|
||||
return IrConstImpl.defaultValueForType(startOffset, endOffset, this)
|
||||
|
||||
val underlyingType = unboxInlineClass()
|
||||
val defaultValueForUnderlyingType = IrConstImpl.defaultValueForType(startOffset, endOffset, underlyingType)
|
||||
return IrCallImpl.fromSymbolOwner(startOffset, endOffset, this, context.ir.symbols.unsafeCoerceIntrinsic).also {
|
||||
it.putTypeArgument(0, underlyingType) // from
|
||||
it.putTypeArgument(1, this) // to
|
||||
it.putValueArgument(0, defaultValueForUnderlyingType)
|
||||
}
|
||||
}
|
||||
|
||||
fun IrDeclaration.getJvmNameFromAnnotation(): String? {
|
||||
// TODO lower @JvmName?
|
||||
val const = getAnnotation(DescriptorUtils.JVM_NAME)?.getValueArgument(0) as? IrConst<*> ?: return null
|
||||
@@ -190,29 +90,6 @@ fun IrValueParameter.isInlineParameter() =
|
||||
// making this return `false` requires using `@Suppress`.
|
||||
(!type.isNullable() || defaultValue?.expression?.type?.isNullable() == false)
|
||||
|
||||
// An IR builder with a reference to the JvmBackendContext
|
||||
class JvmIrBuilder(
|
||||
val backendContext: JvmBackendContext,
|
||||
val symbol: IrSymbol,
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET
|
||||
) : IrBuilderWithScope(
|
||||
IrGeneratorContextBase(backendContext.irBuiltIns),
|
||||
Scope(symbol),
|
||||
startOffset,
|
||||
endOffset
|
||||
) {
|
||||
val irSymbols: JvmSymbols
|
||||
get() = backendContext.ir.symbols
|
||||
}
|
||||
|
||||
fun JvmBackendContext.createJvmIrBuilder(
|
||||
symbol: IrSymbol,
|
||||
startOffset: Int = UNDEFINED_OFFSET,
|
||||
endOffset: Int = UNDEFINED_OFFSET
|
||||
) = JvmIrBuilder(this, symbol, startOffset, endOffset)
|
||||
|
||||
|
||||
fun IrDeclaration.isInCurrentModule(): Boolean =
|
||||
getPackageFragment() is IrFile
|
||||
|
||||
@@ -356,34 +233,6 @@ val IrDeclaration.isStaticInlineClassReplacement: Boolean
|
||||
get() = origin == JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_REPLACEMENT
|
||||
|| origin == JvmLoweredDeclarationOrigin.STATIC_INLINE_CLASS_CONSTRUCTOR
|
||||
|
||||
val IrType.upperBound: IrType
|
||||
get() = erasedUpperBound.symbol.starProjectedType
|
||||
|
||||
fun IrType.eraseToScope(scopeOwner: IrTypeParametersContainer): IrType = eraseToScope(collectVisibleTypeParameters(scopeOwner))
|
||||
|
||||
fun IrType.eraseToScope(visibleTypeParameters: Set<IrTypeParameter>): IrType {
|
||||
require(this is IrSimpleType) { error("Unexpected IrType kind: ${render()}") }
|
||||
return when (classifier) {
|
||||
is IrClassSymbol -> IrSimpleTypeImpl(classifier, hasQuestionMark, arguments.map { it.eraseToScope(visibleTypeParameters) }, annotations)
|
||||
is IrTypeParameterSymbol -> if (classifier.owner in visibleTypeParameters) this else upperBound
|
||||
else -> error("unknown IrType classifier kind: ${classifier.owner.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrTypeArgument.eraseToScope(visibleTypeParameters: Set<IrTypeParameter>): IrTypeArgument = when (this) {
|
||||
is IrStarProjection -> this
|
||||
is IrTypeProjection -> makeTypeProjection(type.eraseToScope(visibleTypeParameters), variance)
|
||||
else -> error("unknown type projection kind: ${render()}")
|
||||
}
|
||||
|
||||
fun collectVisibleTypeParameters(scopeOwner: IrTypeParametersContainer): Set<IrTypeParameter> =
|
||||
generateSequence(scopeOwner) { current ->
|
||||
val parent = current.parent as? IrTypeParametersContainer
|
||||
parent.takeUnless { parent is IrClass && current is IrClass && !current.isInner && !current.isLocal }
|
||||
}
|
||||
.flatMap { it.typeParameters }
|
||||
.toSet()
|
||||
|
||||
// On the IR backend we represent raw types as star projected types with a special synthetic annotation.
|
||||
// See `TypeTranslator.translateTypeAnnotations`.
|
||||
private fun JvmBackendContext.makeRawTypeAnnotation() =
|
||||
@@ -395,18 +244,12 @@ private fun JvmBackendContext.makeRawTypeAnnotation() =
|
||||
fun IrClass.rawType(context: JvmBackendContext): IrType =
|
||||
defaultType.addAnnotations(listOf(context.makeRawTypeAnnotation()))
|
||||
|
||||
fun IrType.getSingleAbstractMethod(): IrSimpleFunction? =
|
||||
getClass()?.getSingleAbstractMethod()
|
||||
|
||||
fun IrClass.getSingleAbstractMethod(): IrSimpleFunction? =
|
||||
functions.singleOrNull { it.modality == Modality.ABSTRACT }
|
||||
|
||||
fun IrFile.getKtFile(): KtFile? =
|
||||
(fileEntry as? PsiIrFileEntry)?.psiFile as KtFile?
|
||||
|
||||
fun IrType.isInlineClassType(): Boolean =
|
||||
erasedUpperBound.isInline
|
||||
|
||||
inline fun IrElement.hasChild(crossinline block: (IrElement) -> Boolean): Boolean {
|
||||
var result = false
|
||||
acceptChildren(object : IrElementVisitorVoid {
|
||||
+1
-1
@@ -140,7 +140,7 @@ internal class SamDelegatingLambdaBuilder(private val jvmContext: JvmBackendCont
|
||||
tmp: IrVariable,
|
||||
parent: IrDeclarationParent
|
||||
): IrSimpleFunction {
|
||||
val superMethod = superType.getSingleAbstractMethod()
|
||||
val superMethod = superType.getClass()?.getSingleAbstractMethod()
|
||||
?: throw AssertionError("SAM type expected: ${superType.render()}")
|
||||
val effectiveValueParametersCount = superMethod.valueParameters.size +
|
||||
if (superMethod.extensionReceiverParameter == null) 0 else 1
|
||||
|
||||
Reference in New Issue
Block a user