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
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<Int>
) : NamedMethodFilter {
private val myTargetMethodName: String
val containingFile = runReadAction { stepTarget.resolvedElement.getContainingFile() }
if (containingFile !is JetFile) return false
init {
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 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())
}
}
@@ -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<Int>
): MethodSmartStepTarget(psiMethod, label, highlightElement, needBreakpointRequest, lines)
public class KotlinMethodSmartStepTarget(
val resolvedElement: JetElement,
label: String,
highlightElement: PsiElement,
lines: Range<Int>
): SmartStepTarget(label, highlightElement, false, 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)) {
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)
}
@@ -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<BasicStepMethodFilter> {
private fun createSmartStepIntoFilters(): List<NamedMethodFilter> {
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<MethodSmartStepTarget>().map {
stepTargets.filterIsInstance<SmartStepTarget>().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()
}
}