Rewrite smart step into kotlin functions, do not use MethodFilter for java because it doesn't work for libraries

This commit is contained in:
Natalia Ukhorskaya
2015-07-16 16:05:53 +03:00
parent d75c21a5a7
commit d8e0d77b66
4 changed files with 59 additions and 32 deletions
@@ -16,29 +16,45 @@
package org.jetbrains.kotlin.idea.debugger.stepping package org.jetbrains.kotlin.idea.debugger.stepping
import com.intellij.debugger.engine.BasicStepMethodFilter
import com.intellij.debugger.engine.DebugProcessImpl import com.intellij.debugger.engine.DebugProcessImpl
import com.intellij.debugger.engine.NamedMethodFilter
import com.intellij.util.Range
import com.sun.jdi.Location import com.sun.jdi.Location
import org.jetbrains.kotlin.idea.debugger.MockSourcePosition import org.jetbrains.kotlin.idea.debugger.MockSourcePosition
import org.jetbrains.kotlin.idea.util.application.runReadAction 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( public class KotlinBasicStepMethodFilter(
val stepTarget: KotlinMethodSmartStepTarget val resolvedFunction: JetElement,
): BasicStepMethodFilter(stepTarget.getMethod(), stepTarget.getCallingExpressionLines()) { val myCallingExpressionLines: Range<Int>
override fun locationMatches(process: DebugProcessImpl, location: Location): Boolean { ) : NamedMethodFilter {
if (super.locationMatches(process, location)) return true private val myTargetMethodName: String
val containingFile = runReadAction { stepTarget.resolvedElement.getContainingFile() } init {
if (containingFile !is JetFile) return false myTargetMethodName = when (resolvedFunction) {
is JetConstructor<*> -> "<init>"
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 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 classes.contains(location.declaringType())
return stepTarget.getMethod().getName() == method.name() &&
myTargetMethodSignature?.getName(process) == method.signature() &&
classes.contains(location.declaringType())
} }
} }
@@ -1,15 +1,20 @@
package org.jetbrains.kotlin.idea.debugger.stepping 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.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.util.Range import com.intellij.util.Range
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.JetElement import org.jetbrains.kotlin.psi.JetElement
public class KotlinMethodSmartStepTarget(val resolvedElement: JetElement, public class KotlinMethodSmartStepTarget(
psiMethod: PsiMethod, val resolvedElement: JetElement,
label: String?, label: String,
highlightElement: PsiElement, highlightElement: PsiElement,
needBreakpointRequest: Boolean, lines: Range<Int>
lines: Range<Int> ): SmartStepTarget(label, highlightElement, false, lines) {
): MethodSmartStepTarget(psiMethod, label, highlightElement, needBreakpointRequest, lines) companion object {
fun calcLabel(descriptor: DeclarationDescriptor): String {
return descriptor.getName().asString()
}
}
}
@@ -140,7 +140,8 @@ public class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() {
if (getter is JetPropertyAccessor && (getter.getBodyExpression() != null || getter.getEqualsToken() != null)) { if (getter is JetPropertyAccessor && (getter.getBodyExpression() != null || getter.getEqualsToken() != null)) {
val psiMethod = LightClassUtil.getLightClassAccessorMethod(getter) val psiMethod = LightClassUtil.getLightClassAccessorMethod(getter)
if (psiMethod != null) { 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) { if (function is JetNamedFunction || function is JetSecondaryConstructor) {
val psiMethod = LightClassUtil.getLightClassMethod(function as JetFunction) val psiMethod = LightClassUtil.getLightClassMethod(function as JetFunction)
if (psiMethod != null) { 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) { if (function is JetNamedFunction || function is JetSecondaryConstructor) {
val psiMethod = LightClassUtil.getLightClassMethod(function as JetFunction) val psiMethod = LightClassUtil.getLightClassMethod(function as JetFunction)
if (psiMethod != null) { 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) { else if (function is PsiMethod) {
@@ -187,7 +190,7 @@ public class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() {
override fun createMethodFilter(stepTarget: SmartStepTarget?): MethodFilter? { override fun createMethodFilter(stepTarget: SmartStepTarget?): MethodFilter? {
return when (stepTarget) { return when (stepTarget) {
is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget) is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget.resolvedElement, stepTarget.getCallingExpressionLines()!!)
is KotlinLambdaSmartStepTarget -> KotlinLambdaMethodFilter(stepTarget.getLambda(), stepTarget.getCallingExpressionLines()!! ) is KotlinLambdaSmartStepTarget -> KotlinLambdaMethodFilter(stepTarget.getLambda(), stepTarget.getCallingExpressionLines()!! )
else -> super.createMethodFilter(stepTarget) else -> super.createMethodFilter(stepTarget)
} }
@@ -18,13 +18,15 @@ package org.jetbrains.kotlin.idea.debugger
import com.intellij.debugger.DebuggerManagerEx import com.intellij.debugger.DebuggerManagerEx
import com.intellij.debugger.actions.MethodSmartStepTarget import com.intellij.debugger.actions.MethodSmartStepTarget
import com.intellij.debugger.actions.SmartStepTarget
import com.intellij.debugger.engine.BasicStepMethodFilter import com.intellij.debugger.engine.BasicStepMethodFilter
import com.intellij.debugger.engine.NamedMethodFilter
import com.intellij.debugger.engine.SuspendContextImpl import com.intellij.debugger.engine.SuspendContextImpl
import com.intellij.debugger.ui.breakpoints.LineBreakpoint import com.intellij.debugger.ui.breakpoints.LineBreakpoint
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.idea.debugger.stepping.KotlinBasicStepMethodFilter 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.KotlinMethodSmartStepTarget
import org.jetbrains.kotlin.idea.debugger.stepping.KotlinSmartStepIntoHandler
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.test.InTextDirectivesUtils.getPrefixedInt import org.jetbrains.kotlin.test.InTextDirectivesUtils.getPrefixedInt
import java.io.File import java.io.File
@@ -96,7 +98,7 @@ public abstract class AbstractKotlinSteppingTest : KotlinDebuggerTestBase() {
} }
} }
private fun createSmartStepIntoFilters(): List<BasicStepMethodFilter> { private fun createSmartStepIntoFilters(): List<NamedMethodFilter> {
val breakpointManager = DebuggerManagerEx.getInstanceEx(getProject())?.getBreakpointManager() val breakpointManager = DebuggerManagerEx.getInstanceEx(getProject())?.getBreakpointManager()
val breakpoint = breakpointManager?.getBreakpoints()?.first { it is LineBreakpoint } val breakpoint = breakpointManager?.getBreakpoints()?.first { it is LineBreakpoint }
@@ -110,13 +112,14 @@ public abstract class AbstractKotlinSteppingTest : KotlinDebuggerTestBase() {
val stepTargets = KotlinSmartStepIntoHandler().findSmartStepTargets(position) val stepTargets = KotlinSmartStepIntoHandler().findSmartStepTargets(position)
stepTargets.filterIsInstance<MethodSmartStepTarget>().map { stepTargets.filterIsInstance<SmartStepTarget>().map {
stepTarget -> stepTarget ->
when (stepTarget) { when (stepTarget) {
is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget) is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget.resolvedElement, stepTarget.getCallingExpressionLines()!!)
else -> BasicStepMethodFilter(stepTarget.getMethod(), stepTarget.getCallingExpressionLines()) is MethodSmartStepTarget -> BasicStepMethodFilter(stepTarget.getMethod(), stepTarget.getCallingExpressionLines())
else -> null
} }
} }
} }.filterNotNull()
} }
} }