Debugger: Simplify method filters, use smart pointer in KotlinLambdaMethodFilter

This commit is contained in:
Yan Zhulanow
2019-11-21 00:57:56 +09:00
parent c6262b5ff2
commit 1a3553cdb7
4 changed files with 29 additions and 41 deletions
@@ -24,20 +24,24 @@ import com.sun.jdi.Location
import org.jetbrains.kotlin.codegen.coroutines.isResumeImplMethodNameFromAnyLanguageSettings import org.jetbrains.kotlin.codegen.coroutines.isResumeImplMethodNameFromAnyLanguageSettings
import org.jetbrains.kotlin.idea.core.util.isMultiLine import org.jetbrains.kotlin.idea.core.util.isMultiLine
import org.jetbrains.kotlin.idea.debugger.isInsideInlineArgument import org.jetbrains.kotlin.idea.debugger.isInsideInlineArgument
import org.jetbrains.kotlin.idea.debugger.safeMethod
import org.jetbrains.kotlin.idea.debugger.stepping.smartStepInto.KotlinLambdaSmartStepTarget
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.KtBlockExpression
import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
class KotlinLambdaMethodFilter( class KotlinLambdaMethodFilter(target: KotlinLambdaSmartStepTarget) : BreakpointStepMethodFilter {
private val lambda: KtFunction, private val lambdaPtr = target.getLambda().createSmartPointer()
private val myCallingExpressionLines: Range<Int>, private val myCallingExpressionLines: Range<Int>? = target.callingExpressionLines
private val isInline: Boolean, private val isInline = target.isInline
private val isSuspend: Boolean private val isSuspend = target.isSuspend
) : BreakpointStepMethodFilter {
private val myFirstStatementPosition: SourcePosition? private val myFirstStatementPosition: SourcePosition?
private val myLastStatementLine: Int private val myLastStatementLine: Int
init { init {
val lambda = target.getLambda()
val body = lambda.bodyExpression val body = lambda.bodyExpression
if (body != null && lambda.isMultiLine()) { if (body != null && lambda.isMultiLine()) {
var firstStatementPosition: SourcePosition? = null var firstStatementPosition: SourcePosition? = null
@@ -51,7 +55,7 @@ class KotlinLambdaMethodFilter(
} }
} }
myFirstStatementPosition = firstStatementPosition myFirstStatementPosition = firstStatementPosition
myLastStatementLine = if (lastStatementPosition != null) lastStatementPosition.line else -1 myLastStatementLine = lastStatementPosition?.line ?: -1
} else { } else {
myFirstStatementPosition = SourcePosition.createFromElement(lambda) myFirstStatementPosition = SourcePosition.createFromElement(lambda)
myLastStatementLine = myFirstStatementPosition!!.line myLastStatementLine = myFirstStatementPosition!!.line
@@ -62,12 +66,13 @@ class KotlinLambdaMethodFilter(
override fun getLastStatementLine() = myLastStatementLine override fun getLastStatementLine() = myLastStatementLine
override fun locationMatches(process: DebugProcessImpl, location: Location): Boolean { override fun locationMatches(process: DebugProcessImpl, location: Location): Boolean {
val method = location.method() val lambda = runReadAction { lambdaPtr.element } ?: return true
if (isInline) { if (isInline) {
return isInsideInlineArgument(lambda, location, process) return isInsideInlineArgument(lambda, location, process)
} }
val method = location.safeMethod() ?: return true
return isLambdaName(method.name()) return isLambdaName(method.name())
} }
@@ -18,26 +18,27 @@ package org.jetbrains.kotlin.idea.debugger.stepping.filter
import com.intellij.debugger.engine.DebugProcessImpl import com.intellij.debugger.engine.DebugProcessImpl
import com.intellij.debugger.engine.NamedMethodFilter import com.intellij.debugger.engine.NamedMethodFilter
import com.intellij.psi.SmartPsiElementPointer
import com.intellij.util.Range import com.intellij.util.Range
import com.sun.jdi.Location import com.sun.jdi.Location
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
import org.jetbrains.kotlin.idea.debugger.stepping.smartStepInto.KotlinMethodSmartStepTarget
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtProperty import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
class KotlinBasicStepMethodFilter( class KotlinOrdinaryMethodFilter(target: KotlinMethodSmartStepTarget) : NamedMethodFilter {
private val declarationPtr: SmartPsiElementPointer<KtDeclaration>?, private val declarationPtr = target.declaration?.createSmartPointer()
private val isInvoke: Boolean, private val isInvoke = target.isInvoke
private val targetMethodName: String, private val targetMethodName = target.targetMethodName
private val myCallingExpressionLines: Range<Int> private val myCallingExpressionLines: Range<Int>? = target.callingExpressionLines
) : NamedMethodFilter {
init { init {
assert(declarationPtr != null || isInvoke) assert(declarationPtr != null || isInvoke)
} }
@@ -81,7 +82,7 @@ class KotlinBasicStepMethodFilter(
} }
// Element is lost. But we know that name is matches, so stop. // Element is lost. But we know that name is matches, so stop.
val declaration = declarationPtr?.element ?: return true val declaration = runReadAction { declarationPtr?.element } ?: return true
val psiManager = currentDeclaration.manager val psiManager = currentDeclaration.manager
if (psiManager.areElementsEquivalent(currentDeclaration, declaration)) { if (psiManager.areElementsEquivalent(currentDeclaration, declaration)) {
@@ -13,10 +13,9 @@ import com.intellij.psi.PsiDocumentManager
import com.intellij.util.Range import com.intellij.util.Range
import com.intellij.util.containers.OrderedSet import com.intellij.util.containers.OrderedSet
import org.jetbrains.kotlin.idea.core.util.CodeInsightUtils.getTopmostElementAtOffset import org.jetbrains.kotlin.idea.core.util.CodeInsightUtils.getTopmostElementAtOffset
import org.jetbrains.kotlin.idea.debugger.stepping.filter.KotlinBasicStepMethodFilter import org.jetbrains.kotlin.idea.debugger.stepping.filter.KotlinOrdinaryMethodFilter
import org.jetbrains.kotlin.idea.debugger.stepping.filter.KotlinLambdaMethodFilter import org.jetbrains.kotlin.idea.debugger.stepping.filter.KotlinLambdaMethodFilter
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() {
@@ -40,15 +39,8 @@ class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() {
override fun createMethodFilter(stepTarget: SmartStepTarget?): MethodFilter? { override fun createMethodFilter(stepTarget: SmartStepTarget?): MethodFilter? {
return when (stepTarget) { return when (stepTarget) {
is KotlinMethodSmartStepTarget -> { is KotlinMethodSmartStepTarget -> KotlinOrdinaryMethodFilter(stepTarget)
val declarationPtr = stepTarget.declaration?.createSmartPointer() is KotlinLambdaSmartStepTarget -> KotlinLambdaMethodFilter(stepTarget)
val lines = stepTarget.callingExpressionLines ?: return null
KotlinBasicStepMethodFilter(declarationPtr, stepTarget.isInvoke, stepTarget.targetMethodName, lines)
}
is KotlinLambdaSmartStepTarget -> {
val lines = stepTarget.callingExpressionLines ?: return null
KotlinLambdaMethodFilter(stepTarget.getLambda(), lines, stepTarget.isInline, stepTarget.isSuspend)
}
else -> super.createMethodFilter(stepTarget) else -> super.createMethodFilter(stepTarget)
} }
} }
@@ -14,7 +14,7 @@ import com.intellij.debugger.impl.PositionUtil
import com.intellij.execution.process.ProcessOutputTypes import com.intellij.execution.process.ProcessOutputTypes
import com.sun.jdi.request.StepRequest import com.sun.jdi.request.StepRequest
import org.jetbrains.kotlin.idea.debugger.stepping.* import org.jetbrains.kotlin.idea.debugger.stepping.*
import org.jetbrains.kotlin.idea.debugger.stepping.filter.KotlinBasicStepMethodFilter import org.jetbrains.kotlin.idea.debugger.stepping.filter.KotlinOrdinaryMethodFilter
import org.jetbrains.kotlin.idea.debugger.stepping.filter.KotlinLambdaMethodFilter import org.jetbrains.kotlin.idea.debugger.stepping.filter.KotlinLambdaMethodFilter
import org.jetbrains.kotlin.idea.debugger.stepping.smartStepInto.KotlinLambdaSmartStepTarget import org.jetbrains.kotlin.idea.debugger.stepping.smartStepInto.KotlinLambdaSmartStepTarget
import org.jetbrains.kotlin.idea.debugger.stepping.smartStepInto.KotlinMethodSmartStepTarget import org.jetbrains.kotlin.idea.debugger.stepping.smartStepInto.KotlinMethodSmartStepTarget
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.idea.debugger.test.util.SteppingInstruction
import org.jetbrains.kotlin.idea.debugger.test.util.SteppingInstructionKind import org.jetbrains.kotlin.idea.debugger.test.util.SteppingInstructionKind
import org.jetbrains.kotlin.idea.debugger.test.util.renderSourcePosition import org.jetbrains.kotlin.idea.debugger.test.util.renderSourcePosition
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
@@ -151,17 +150,8 @@ abstract class KotlinDescriptorTestCaseWithStepping : KotlinDescriptorTestCase()
val stepTargets = KotlinSmartStepIntoHandler().findSmartStepTargets(position) val stepTargets = KotlinSmartStepIntoHandler().findSmartStepTargets(position)
stepTargets.mapNotNull { stepTarget -> stepTargets.mapNotNull { stepTarget ->
when (stepTarget) { when (stepTarget) {
is KotlinLambdaSmartStepTarget -> is KotlinLambdaSmartStepTarget -> KotlinLambdaMethodFilter(stepTarget)
KotlinLambdaMethodFilter( is KotlinMethodSmartStepTarget -> KotlinOrdinaryMethodFilter(stepTarget)
stepTarget.getLambda(), stepTarget.getCallingExpressionLines()!!, stepTarget.isInline, stepTarget.isSuspend
)
is KotlinMethodSmartStepTarget ->
KotlinBasicStepMethodFilter(
stepTarget.declaration?.createSmartPointer(),
stepTarget.isInvoke,
stepTarget.targetMethodName,
stepTarget.getCallingExpressionLines()!!
)
is MethodSmartStepTarget -> BasicStepMethodFilter(stepTarget.method, stepTarget.getCallingExpressionLines()) is MethodSmartStepTarget -> BasicStepMethodFilter(stepTarget.method, stepTarget.getCallingExpressionLines())
else -> null else -> null
} }