Add call checker to report error more granulary if possible

This, however, works only for calls of 'synchronized' only. Thus, it
does not support inline functions of any kind.
This commit is contained in:
Ilmir Usmanov
2018-09-28 21:20:40 +03:00
parent 281f09f077
commit 9af7316845
21 changed files with 327 additions and 86 deletions
@@ -5,11 +5,11 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.backend.common.isTopLevelInPackage
import org.jetbrains.kotlin.codegen.coroutines.createCustomCopy
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.JVMAssertionsMode
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.isTopLevelInPackage
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.BindingTraceContext
import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.backend.common.isTopLevelInPackage
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.builtins.PrimitiveType
@@ -138,10 +138,7 @@ class CoroutineTransformerMethodVisitor(
val suspendMarkerVarIndex = methodNode.maxLocals++
val suspensionPointLineNumbers =
suspensionPoints.map { suspensionPoint ->
suspensionPoint.suspensionCallBegin.findPreviousOrNull { it is LineNumberNode } as LineNumberNode?
}
val suspensionPointLineNumbers = suspensionPoints.map { findSuspensionPointLineNumber(it) }
val continuationLabels = suspensionPoints.withIndex().map {
transformCallAndReturnContinuationLabel(it.index + 1, it.value, methodNode, suspendMarkerVarIndex)
@@ -200,6 +197,9 @@ class CoroutineTransformerMethodVisitor(
}
}
private fun findSuspensionPointLineNumber(suspensionPoint: SuspensionPoint) =
suspensionPoint.suspensionCallBegin.findPreviousOrNull { it is LineNumberNode } as LineNumberNode?
private fun checkForSuspensionPointInsideMonitor(methodNode: MethodNode, suspensionPoints: List<SuspensionPoint>) {
if (methodNode.instructions.asSequence().none { it.opcode == Opcodes.MONITORENTER }) return
@@ -225,7 +225,13 @@ class CoroutineTransformerMethodVisitor(
for (suspensionPoint in suspensionPoints) {
if (monitorDepthMap[suspensionPoint.suspensionCallBegin]?.let { it > 0 } == true) {
// TODO: Support crossinline suspend lambdas
element?.let { diagnostics.report(ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR.on(it)) }
val stackTraceElement = StackTraceElement(
containingClassInternalName,
methodNode.name,
sourceFile,
findSuspensionPointLineNumber(suspensionPoint)?.line ?: -1
)
element?.let { diagnostics.report(ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR.on(it, "$stackTraceElement")) }
return
}
}