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:
+2
-1
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
|
||||
import org.jetbrains.kotlin.ir.types.impl.ReturnTypeIsNotInitializedException
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
@@ -54,7 +55,7 @@ class IrConstructorImpl(
|
||||
|
||||
override var returnType: IrType = returnType
|
||||
get() = if (field === IrUninitializedType) {
|
||||
error("Return type is not initialized")
|
||||
throw ReturnTypeIsNotInitializedException(this)
|
||||
} else {
|
||||
field
|
||||
}
|
||||
|
||||
+3
-2
@@ -5,9 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations.impl
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
|
||||
import org.jetbrains.kotlin.ir.types.impl.ReturnTypeIsNotInitializedException
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
@@ -44,7 +45,7 @@ abstract class IrFunctionCommonImpl(
|
||||
|
||||
override var returnType: IrType = returnType
|
||||
get() = if (field === IrUninitializedType) {
|
||||
error("Return type is not initialized")
|
||||
throw ReturnTypeIsNotInitializedException(this)
|
||||
} else {
|
||||
field
|
||||
}
|
||||
|
||||
+2
-1
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
|
||||
import org.jetbrains.kotlin.ir.types.impl.ReturnTypeIsNotInitializedException
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
@@ -73,7 +74,7 @@ internal class PersistentIrConstructor(
|
||||
|
||||
override var returnType: IrType
|
||||
get() = returnTypeField.let {
|
||||
if (it !== IrUninitializedType) it else error("Return type is not initialized")
|
||||
if (it !== IrUninitializedType) it else throw ReturnTypeIsNotInitializedException(this)
|
||||
}
|
||||
set(c) {
|
||||
returnTypeField = c
|
||||
|
||||
+3
-2
@@ -5,9 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations.persistent
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.persistent.carriers.Carrier
|
||||
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
|
||||
import org.jetbrains.kotlin.ir.types.impl.ReturnTypeIsNotInitializedException
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
@@ -63,7 +64,7 @@ internal abstract class PersistentIrFunctionCommon(
|
||||
|
||||
final override var returnType: IrType
|
||||
get() = returnTypeField.let {
|
||||
if (it !== IrUninitializedType) it else error("Return type is not initialized")
|
||||
if (it !== IrUninitializedType) it else throw ReturnTypeIsNotInitializedException(this)
|
||||
}
|
||||
set(c) {
|
||||
returnTypeField = c
|
||||
|
||||
@@ -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