Smart step into for constructors
This commit is contained in:
+7
-11
@@ -21,26 +21,22 @@ 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.Method
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi.KtConstructor
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
public class KotlinBasicStepMethodFilter(
|
||||
val resolvedFunction: KtElement,
|
||||
val resolvedElement: KtElement,
|
||||
val myCallingExpressionLines: Range<Int>
|
||||
) : NamedMethodFilter {
|
||||
private val myTargetMethodName: String
|
||||
|
||||
init {
|
||||
myTargetMethodName = when (resolvedFunction) {
|
||||
myTargetMethodName = when (resolvedElement) {
|
||||
is KtAnonymousInitializer -> "<init>"
|
||||
is KtConstructor<*> -> "<init>"
|
||||
is KtPropertyAccessor -> JvmAbi.getterName((resolvedFunction.getParent() as KtProperty).getName()!!)
|
||||
else -> resolvedFunction.getName()!!
|
||||
is KtPropertyAccessor -> JvmAbi.getterName((resolvedElement.getParent() as KtProperty).getName()!!)
|
||||
else -> resolvedElement.getName()!!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +48,7 @@ public class KotlinBasicStepMethodFilter(
|
||||
val method = location.method()
|
||||
if (myTargetMethodName != method.name()) return false
|
||||
|
||||
val sourcePosition = runReadAction { SourcePosition.createFromElement(resolvedFunction) } ?: return false
|
||||
val sourcePosition = runReadAction { SourcePosition.createFromElement(resolvedElement) } ?: return false
|
||||
val positionManager = process.getPositionManager() ?: return false
|
||||
|
||||
val classes = positionManager.getAllClasses(sourcePosition)
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.util.Range
|
||||
import com.intellij.util.containers.OrderedSet
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
||||
@@ -64,7 +65,6 @@ public class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() {
|
||||
|
||||
// TODO support class initializers, local functions, delegated properties with specified type, setter for properties
|
||||
element.accept(object: KtTreeVisitorVoid() {
|
||||
|
||||
override fun visitFunctionLiteralExpression(expression: KtFunctionLiteralExpression) {
|
||||
recordFunctionLiteral(expression.functionLiteral)
|
||||
}
|
||||
@@ -175,14 +175,20 @@ public class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() {
|
||||
val resolvedCall = expression.getResolvedCall(bindingContext) ?: return
|
||||
|
||||
val descriptor = resolvedCall.getResultingDescriptor()
|
||||
if (descriptor is CallableMemberDescriptor && !isIntrinsic(descriptor)) {
|
||||
val function = DescriptorToSourceUtilsIde.getAnyDeclaration(file.getProject(), descriptor)
|
||||
if (function is KtNamedFunction || function is KtSecondaryConstructor) {
|
||||
if (descriptor is FunctionDescriptor && !isIntrinsic(descriptor)) {
|
||||
val resolvedElement = DescriptorToSourceUtilsIde.getAnyDeclaration(file.getProject(), descriptor)
|
||||
if (resolvedElement is KtNamedFunction || resolvedElement is KtConstructor<*>) {
|
||||
val label = KotlinMethodSmartStepTarget.calcLabel(descriptor)
|
||||
result.add(KotlinMethodSmartStepTarget(function as KtFunction, label, expression, lines))
|
||||
result.add(KotlinMethodSmartStepTarget(resolvedElement as KtFunction, label, expression, lines))
|
||||
}
|
||||
else if (function is PsiMethod) {
|
||||
result.add(MethodSmartStepTarget(function, null, expression, false, lines))
|
||||
else if (resolvedElement is PsiMethod) {
|
||||
result.add(MethodSmartStepTarget(resolvedElement, null, expression, false, lines))
|
||||
}
|
||||
else if (resolvedElement is KtClass) {
|
||||
resolvedElement.getAnonymousInitializers().firstOrNull()?.let {
|
||||
val label = KotlinMethodSmartStepTarget.calcLabel(descriptor)
|
||||
result.add(KotlinMethodSmartStepTarget(it, label, expression, lines))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
fun foo() {
|
||||
println("${A()} ${B()} ${C(1)} ${D()} ${E(1)} ${F()} ${G()} ${J()} ${K(1)} ${L()}")<caret>
|
||||
}
|
||||
|
||||
class A
|
||||
class B()
|
||||
class C(val a: Int)
|
||||
class D {
|
||||
constructor()
|
||||
}
|
||||
class E {
|
||||
constructor(i: Int)
|
||||
}
|
||||
class F {
|
||||
constructor() {
|
||||
|
||||
}
|
||||
}
|
||||
class G {
|
||||
constructor(i: Int) {
|
||||
|
||||
}
|
||||
}
|
||||
class J {
|
||||
init {
|
||||
|
||||
}
|
||||
}
|
||||
class K(val a: Int) {
|
||||
init {
|
||||
|
||||
}
|
||||
}
|
||||
class L {
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// EXISTS: println(Any?), constructor B(), constructor C(Int), constructor D(), constructor E(Int), constructor F(), constructor G(Int), constructor J(), constructor K(Int), constructor L()
|
||||
@@ -25,4 +25,5 @@ val propFoo: Int
|
||||
// EXISTS: fooWithParam: f.invoke()
|
||||
// EXISTS: test()
|
||||
// EXISTS: constructor FooClass()
|
||||
// EXISTS: constructor FooClass(Int)
|
||||
// EXISTS: constructor FooClass(Int\, Int)
|
||||
@@ -53,6 +53,12 @@ public class SmartStepIntoTestGenerated extends AbstractSmartStepIntoTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("constructor.kt")
|
||||
public void testConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/smartStepInto/constructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("conventionMethod.kt")
|
||||
public void testConventionMethod() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/smartStepInto/conventionMethod.kt");
|
||||
|
||||
Reference in New Issue
Block a user