[JVM] report error instead of exception on missing inline body
^KT-14840 Fixed
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt
index 157d5d6..fd9c148 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/SourceCompilerForInline.kt
@@ -126,7 +126,7 @@
getMethodNode(bytes, owner) { methodToFind == Method(removeModuleSuffixOrNull(it.name), it.descriptor) }?.let { return it }
}
}
- throw IllegalStateException("couldn't find inline method $owner.$method")
+ throw InlineMethodBodyMissingException("$owner.$method")
}
private fun removeModuleSuffixOrNull(name: String): String? {
@@ -138,3 +138,6 @@
private fun getMethodNode(owner: Type, bytes: ByteArray, method: Method, isSuspend: Boolean) =
(if (isSuspend) getMethodNode(bytes, owner, Method(method.name + FOR_INLINE_SUFFIX, method.descriptor)) else null)
?: getMethodNode(bytes, owner, method)
+
+class InlineMethodBodyMissingException(val jvmMethod: String) :
+ InlineException("couldn't find inline method $jvmMethod")
\ No newline at end of file
diff --git a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt
index c7b4920..7df0a6d 100644
--- a/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt
+++ b/compiler/ir/backend.jvm/codegen/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt
@@ -6,7 +6,9 @@
package org.jetbrains.kotlin.backend.jvm.codegen
import com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.backend.jvm.JvmBackendErrors
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
+import org.jetbrains.kotlin.backend.jvm.ir.fileParent
import org.jetbrains.kotlin.backend.jvm.ir.isInlineOnly
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
import org.jetbrains.kotlin.backend.jvm.ir.unwrapInlineLambda
@@ -72,6 +74,9 @@
state.factory.removeClasses(result.calcClassesToRemove())
} catch (e: CompilationException) {
throw e
+ } catch (e: InlineMethodBodyMissingException) {
+ codegen.context.ktDiagnosticReporter.at(expression, codegen.irFunction.fileParent)
+ .report(JvmBackendErrors.INLINE_MISSING_BODY, e.jvmMethod)
} catch (e: InlineException) {
throw CompilationException(
"Couldn't inline method call: ${sourceCompiler.callElementText}",
@@ -253,7 +258,12 @@
if (function.parameters.isEmpty()) return false
if (function.parameters.any { it.isInlineParameter() }) return false
- return canInlineArgumentsInPlace(sourceCompiler.compileInlineFunction(jvmSignature).node)
+ val compiledNode = try {
+ sourceCompiler.compileInlineFunction(jvmSignature).node
+ } catch (_: InlineException) {
+ return false
+ }
+ return canInlineArgumentsInPlace(compiledNode)
}
private fun inlineCall(nodeAndSmap: SMAPAndMethodNode, isInlineOnly: Boolean): InlineResult {
diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt
index 3081b93..8ed9d10 100644
--- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt
+++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt
@@ -24,6 +24,7 @@
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.backend.common.originalBeforeInline
+import org.jetbrains.kotlin.codegen.inline.InlineException
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrTypeProjection
@@ -283,14 +284,19 @@
val nonDispatchIndex = parameter.indexInParameters - hasDispatchReceiverAsInt
val localIndex = signature.parameters.take(nonDispatchIndex).sumOf { it.size } + hasDispatchReceiverAsInt
// Null checks are removed during inlining, so we can ignore them.
- return loadCompiledInlineFunction(
- containerId,
- signature.asmMethod,
- isSuspend,
- hasMangledReturnType,
- context.evaluatorData != null && visibility == DescriptorVisibilities.INTERNAL,
- context.state
- ).node.usesLocalExceptParameterNullCheck(localIndex)
+ val compiledInlineNode = try {
+ loadCompiledInlineFunction(
+ containerId,
+ signature.asmMethod,
+ isSuspend,
+ hasMangledReturnType,
+ context.evaluatorData != null && visibility == DescriptorVisibilities.INTERNAL,
+ context.state
+ ).node
+ } catch (_: InlineException) {
+ return false
+ }
+ return compiledInlineNode.usesLocalExceptParameterNullCheck(localIndex)
}
return hasChild { it is IrGetValue && it.symbol == parameters[parameter.indexInParameters].symbol }
}
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendErrors.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendErrors.kt
index 83a5bdf2..8d0b5c5 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendErrors.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendErrors.kt
@@ -30,6 +30,7 @@
val SCRIPT_CAPTURING_ENUM_ENTRY by error1<PsiElement, String>()
val INLINE_CALL_CYCLE by error1<PsiElement, Name>()
+ val INLINE_MISSING_BODY by error1<PsiElement, String>()
val NOT_ALL_MULTIFILE_CLASS_PARTS_ARE_JVM_SYNTHETIC by error0<PsiElement>()
@@ -56,6 +57,7 @@
map.put(JvmBackendErrors.SCRIPT_CAPTURING_ENUM_ENTRY, "Enum entry {0} captures the script class instance. Try to use class or anonymous object instead", STRING)
map.put(JvmBackendErrors.INLINE_CALL_CYCLE, "The ''{0}'' invocation is a part of inline cycle", NAME)
+ map.put(JvmBackendErrors.INLINE_MISSING_BODY,"Missing inline method body for ''{0}''. Please verify that the owning class file is not modified by a third-party tool like Proguard",STRING)
map.put(
JvmBackendErrors.NOT_ALL_MULTIFILE_CLASS_PARTS_ARE_JVM_SYNTHETIC,
"All of multi-file class parts should be annotated with @JvmSynthetic if at least one of them is"