From d8e0d77b6673267dd17ee0d5eea017e9c5ca1f51 Mon Sep 17 00:00:00 2001 From: Natalia Ukhorskaya Date: Thu, 16 Jul 2015 16:05:53 +0300 Subject: [PATCH] Rewrite smart step into kotlin functions, do not use MethodFilter for java because it doesn't work for libraries --- .../stepping/KotlinBasicStepMethodFilter.kt | 42 +++++++++++++------ .../KotlinMethodSmartStepIntoTarget.kt | 23 ++++++---- .../stepping/KotlinSmartStepIntoHandler.kt | 11 +++-- .../debugger/AbstractKotlinSteppingTest.kt | 15 ++++--- 4 files changed, 59 insertions(+), 32 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinBasicStepMethodFilter.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinBasicStepMethodFilter.kt index bb15ab24135..1e6b9d393cc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinBasicStepMethodFilter.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinBasicStepMethodFilter.kt @@ -16,29 +16,45 @@ package org.jetbrains.kotlin.idea.debugger.stepping -import com.intellij.debugger.engine.BasicStepMethodFilter import com.intellij.debugger.engine.DebugProcessImpl +import com.intellij.debugger.engine.NamedMethodFilter +import com.intellij.util.Range import com.sun.jdi.Location import org.jetbrains.kotlin.idea.debugger.MockSourcePosition import org.jetbrains.kotlin.idea.util.application.runReadAction -import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.load.java.JvmAbi +import org.jetbrains.kotlin.psi.JetConstructor +import org.jetbrains.kotlin.psi.JetElement +import org.jetbrains.kotlin.psi.JetProperty +import org.jetbrains.kotlin.psi.JetPropertyAccessor public class KotlinBasicStepMethodFilter( - val stepTarget: KotlinMethodSmartStepTarget -): BasicStepMethodFilter(stepTarget.getMethod(), stepTarget.getCallingExpressionLines()) { - override fun locationMatches(process: DebugProcessImpl, location: Location): Boolean { - if (super.locationMatches(process, location)) return true + val resolvedFunction: JetElement, + val myCallingExpressionLines: Range +) : NamedMethodFilter { + private val myTargetMethodName: String - val containingFile = runReadAction { stepTarget.resolvedElement.getContainingFile() } - if (containingFile !is JetFile) return false + init { + myTargetMethodName = when (resolvedFunction) { + is JetConstructor<*> -> "" + is JetPropertyAccessor -> JvmAbi.getterName((resolvedFunction.getParent() as JetProperty).getName()!!) + else -> resolvedFunction.getName()!! + } + } + + override fun getCallingExpressionLines() = myCallingExpressionLines + + override fun getMethodName() = myTargetMethodName + + override fun locationMatches(process: DebugProcessImpl, location: Location): Boolean { + val method = location.method() + if (myTargetMethodName != method.name()) return false val positionManager = process.getPositionManager() ?: return false - val classes = positionManager.getAllClasses(MockSourcePosition(_file = containingFile, _elementAt = stepTarget.resolvedElement)) + val containingFile = runReadAction { resolvedFunction.getContainingJetFile() } + val classes = positionManager.getAllClasses(MockSourcePosition(_file = containingFile, _elementAt = resolvedFunction)) - val method = location.method() - return stepTarget.getMethod().getName() == method.name() && - myTargetMethodSignature?.getName(process) == method.signature() && - classes.contains(location.declaringType()) + return classes.contains(location.declaringType()) } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinMethodSmartStepIntoTarget.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinMethodSmartStepIntoTarget.kt index c78c52d5e53..3e0b7afa298 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinMethodSmartStepIntoTarget.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinMethodSmartStepIntoTarget.kt @@ -1,15 +1,20 @@ package org.jetbrains.kotlin.idea.debugger.stepping -import com.intellij.debugger.actions.MethodSmartStepTarget +import com.intellij.debugger.actions.SmartStepTarget import com.intellij.psi.PsiElement -import com.intellij.psi.PsiMethod import com.intellij.util.Range +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.psi.JetElement -public class KotlinMethodSmartStepTarget(val resolvedElement: JetElement, - psiMethod: PsiMethod, - label: String?, - highlightElement: PsiElement, - needBreakpointRequest: Boolean, - lines: Range -): MethodSmartStepTarget(psiMethod, label, highlightElement, needBreakpointRequest, lines) \ No newline at end of file +public class KotlinMethodSmartStepTarget( + val resolvedElement: JetElement, + label: String, + highlightElement: PsiElement, + lines: Range +): SmartStepTarget(label, highlightElement, false, lines) { + companion object { + fun calcLabel(descriptor: DeclarationDescriptor): String { + return descriptor.getName().asString() + } + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSmartStepIntoHandler.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSmartStepIntoHandler.kt index 9c0ee2cacba..79ce86b0cde 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSmartStepIntoHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSmartStepIntoHandler.kt @@ -140,7 +140,8 @@ public class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { if (getter is JetPropertyAccessor && (getter.getBodyExpression() != null || getter.getEqualsToken() != null)) { val psiMethod = LightClassUtil.getLightClassAccessorMethod(getter) if (psiMethod != null) { - result.add(KotlinMethodSmartStepTarget(getter, psiMethod, null, expression, false, lines)) + val label = KotlinMethodSmartStepTarget.calcLabel(getterDescriptor) + result.add(KotlinMethodSmartStepTarget(getter, label, expression, lines)) } } } @@ -151,7 +152,8 @@ public class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { if (function is JetNamedFunction || function is JetSecondaryConstructor) { val psiMethod = LightClassUtil.getLightClassMethod(function as JetFunction) if (psiMethod != null) { - result.add(KotlinMethodSmartStepTarget(function, psiMethod, "${propertyDescriptor.getName()}.", expression, false, lines)) + val label = "${propertyDescriptor.getName()}." + KotlinMethodSmartStepTarget.calcLabel(delegatedPropertyGetterDescriptor) + result.add(KotlinMethodSmartStepTarget(function, label, expression, lines)) } } } @@ -172,7 +174,8 @@ public class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { if (function is JetNamedFunction || function is JetSecondaryConstructor) { val psiMethod = LightClassUtil.getLightClassMethod(function as JetFunction) if (psiMethod != null) { - result.add(KotlinMethodSmartStepTarget(function, psiMethod, null, expression, false, lines)) + val label = KotlinMethodSmartStepTarget.calcLabel(descriptor) + result.add(KotlinMethodSmartStepTarget(function, label, expression, lines)) } } else if (function is PsiMethod) { @@ -187,7 +190,7 @@ public class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { override fun createMethodFilter(stepTarget: SmartStepTarget?): MethodFilter? { return when (stepTarget) { - is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget) + is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget.resolvedElement, stepTarget.getCallingExpressionLines()!!) is KotlinLambdaSmartStepTarget -> KotlinLambdaMethodFilter(stepTarget.getLambda(), stepTarget.getCallingExpressionLines()!! ) else -> super.createMethodFilter(stepTarget) } diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractKotlinSteppingTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractKotlinSteppingTest.kt index bab52c3683e..e508517d152 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractKotlinSteppingTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractKotlinSteppingTest.kt @@ -18,13 +18,15 @@ package org.jetbrains.kotlin.idea.debugger import com.intellij.debugger.DebuggerManagerEx import com.intellij.debugger.actions.MethodSmartStepTarget +import com.intellij.debugger.actions.SmartStepTarget import com.intellij.debugger.engine.BasicStepMethodFilter +import com.intellij.debugger.engine.NamedMethodFilter import com.intellij.debugger.engine.SuspendContextImpl import com.intellij.debugger.ui.breakpoints.LineBreakpoint import com.intellij.openapi.util.io.FileUtil import org.jetbrains.kotlin.idea.debugger.stepping.KotlinBasicStepMethodFilter -import org.jetbrains.kotlin.idea.debugger.stepping.KotlinSmartStepIntoHandler import org.jetbrains.kotlin.idea.debugger.stepping.KotlinMethodSmartStepTarget +import org.jetbrains.kotlin.idea.debugger.stepping.KotlinSmartStepIntoHandler import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.test.InTextDirectivesUtils.getPrefixedInt import java.io.File @@ -96,7 +98,7 @@ public abstract class AbstractKotlinSteppingTest : KotlinDebuggerTestBase() { } } - private fun createSmartStepIntoFilters(): List { + private fun createSmartStepIntoFilters(): List { val breakpointManager = DebuggerManagerEx.getInstanceEx(getProject())?.getBreakpointManager() val breakpoint = breakpointManager?.getBreakpoints()?.first { it is LineBreakpoint } @@ -110,13 +112,14 @@ public abstract class AbstractKotlinSteppingTest : KotlinDebuggerTestBase() { val stepTargets = KotlinSmartStepIntoHandler().findSmartStepTargets(position) - stepTargets.filterIsInstance().map { + stepTargets.filterIsInstance().map { stepTarget -> when (stepTarget) { - is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget) - else -> BasicStepMethodFilter(stepTarget.getMethod(), stepTarget.getCallingExpressionLines()) + is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget.resolvedElement, stepTarget.getCallingExpressionLines()!!) + is MethodSmartStepTarget -> BasicStepMethodFilter(stepTarget.getMethod(), stepTarget.getCallingExpressionLines()) + else -> null } } - } + }.filterNotNull() } }