IR: do not crash renderer on functions with uninitialized return type
This is a follow-up to b497f39c29. It
turns out that it didn't help because `IrFunction.returnType` throws
exception, and checking for `IrUninitializedType` in `IrType.render` was
already too late. Throw and catch specific exception instead.
Also add function name into the exception message for better diagnostics
elsewhere (can't compute the full FQ name because in cases like
KT-42020, the parent is also uninitialized).
This commit is contained in:
@@ -5,8 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.types.impl
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
@@ -63,3 +65,7 @@ object IrUninitializedType : IrType {
|
||||
|
||||
override fun hashCode(): Int = System.identityHashCode(this)
|
||||
}
|
||||
|
||||
class ReturnTypeIsNotInitializedException(function: IrFunction) : IllegalStateException(
|
||||
"Return type is not initialized for function '${function.name}'"
|
||||
)
|
||||
|
||||
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
|
||||
import org.jetbrains.kotlin.ir.types.impl.ReturnTypeIsNotInitializedException
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
@@ -108,8 +108,7 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false) : IrEl
|
||||
run(fn).trimEnd()
|
||||
|
||||
private fun IrType.render(): String =
|
||||
if (this === IrUninitializedType) "<Uninitialized>"
|
||||
else "${renderTypeAnnotations(annotations)}${renderTypeInner()}"
|
||||
"${renderTypeAnnotations(annotations)}${renderTypeInner()}"
|
||||
|
||||
private fun IrType.renderTypeInner() =
|
||||
when (this) {
|
||||
@@ -252,7 +251,7 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false) : IrEl
|
||||
|
||||
if (declaration is IrSimpleFunction) {
|
||||
append(": ")
|
||||
append(declaration.returnType.render())
|
||||
append(declaration.renderReturnType())
|
||||
}
|
||||
append(' ')
|
||||
|
||||
@@ -282,8 +281,11 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false) : IrEl
|
||||
|
||||
append(declaration.name.asString())
|
||||
|
||||
val type = declaration.getter?.returnType ?: declaration.backingField?.type
|
||||
if (type != null) {
|
||||
val getter = declaration.getter
|
||||
if (getter != null) {
|
||||
append(": ")
|
||||
append(getter.renderReturnType())
|
||||
} else declaration.backingField?.type?.let { type ->
|
||||
append(": ")
|
||||
append(type.render())
|
||||
}
|
||||
@@ -367,10 +369,20 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false) : IrEl
|
||||
"name:$name visibility:$visibility modality:$modality " +
|
||||
renderTypeParameters() + " " +
|
||||
renderValueParameterTypes() + " " +
|
||||
"returnType:${returnType.render()} " +
|
||||
"returnType:${renderReturnType()} " +
|
||||
renderSimpleFunctionFlags()
|
||||
}
|
||||
|
||||
private fun IrFunction.renderReturnType(): String =
|
||||
safeReturnType?.render() ?: "<Uninitialized>"
|
||||
|
||||
private val IrFunction.safeReturnType: IrType?
|
||||
get() = try {
|
||||
returnType
|
||||
} catch (e: ReturnTypeIsNotInitializedException) {
|
||||
null
|
||||
}
|
||||
|
||||
private fun renderFlagsList(vararg flags: String?) =
|
||||
flags.filterNotNull().run {
|
||||
if (isNotEmpty())
|
||||
@@ -407,7 +419,7 @@ class RenderIrElementVisitor(private val normalizeNames: Boolean = false) : IrEl
|
||||
"visibility:$visibility " +
|
||||
renderTypeParameters() + " " +
|
||||
renderValueParameterTypes() + " " +
|
||||
"returnType:${returnType.render()} " +
|
||||
"returnType:${renderReturnType()} " +
|
||||
renderConstructorFlags()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user