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 3e0b7afa298..cc706e37181 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinMethodSmartStepIntoTarget.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinMethodSmartStepIntoTarget.kt @@ -4,7 +4,12 @@ import com.intellij.debugger.actions.SmartStepTarget import com.intellij.psi.PsiElement import com.intellij.util.Range import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.idea.JetIcons +import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.psi.JetElement +import org.jetbrains.kotlin.psi.JetNamedFunction +import org.jetbrains.kotlin.renderer.ParameterNameRenderingPolicy +import javax.swing.Icon public class KotlinMethodSmartStepTarget( val resolvedElement: JetElement, @@ -12,9 +17,34 @@ public class KotlinMethodSmartStepTarget( highlightElement: PsiElement, lines: Range ): SmartStepTarget(label, highlightElement, false, lines) { - companion object { - fun calcLabel(descriptor: DeclarationDescriptor): String { - return descriptor.getName().asString() + override fun getIcon(): Icon? { + return when { + resolvedElement is JetNamedFunction && resolvedElement.getReceiverTypeReference() != null -> JetIcons.EXTENSION_FUNCTION + else -> JetIcons.FUNCTION } } + + companion object { + private val renderer = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.withOptions { + parameterNameRenderingPolicy = ParameterNameRenderingPolicy.NONE + withoutReturnType = true + renderAccessors = true + startFromName = true + modifiers = emptySet() + } + + fun calcLabel(descriptor: DeclarationDescriptor): String { + return renderer.render(descriptor) + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + + if (other == null || other !is KotlinMethodSmartStepTarget) return false + + return resolvedElement == other.resolvedElement + } + + override fun hashCode() = resolvedElement.hashCode() } \ No newline at end of file diff --git a/idea/testData/debugger/smartStepInto/arrayAccess.kt b/idea/testData/debugger/smartStepInto/arrayAccess.kt index d45350bbb9c..762cef96ae6 100644 --- a/idea/testData/debugger/smartStepInto/arrayAccess.kt +++ b/idea/testData/debugger/smartStepInto/arrayAccess.kt @@ -7,4 +7,4 @@ class A { fun get(i: Int) = 1 } -// EXISTS: get(int) \ No newline at end of file +// EXISTS: get(Int) \ No newline at end of file diff --git a/idea/testData/debugger/smartStepInto/delegatedPropertyGetter.kt b/idea/testData/debugger/smartStepInto/delegatedPropertyGetter.kt index 61996cb63f3..2eb161d5b31 100644 --- a/idea/testData/debugger/smartStepInto/delegatedPropertyGetter.kt +++ b/idea/testData/debugger/smartStepInto/delegatedPropertyGetter.kt @@ -8,4 +8,4 @@ class Delegate { fun get(t: Any?, p: PropertyMetadata) = 1 } -// EXISTS: a.get(Object\, PropertyMetadata) \ No newline at end of file +// EXISTS: a.get(Any?\, PropertyMetadata) \ No newline at end of file diff --git a/idea/testData/debugger/smartStepInto/dotQualifiedInParam.kt b/idea/testData/debugger/smartStepInto/dotQualifiedInParam.kt index 57471ec6a85..18ef309333d 100644 --- a/idea/testData/debugger/smartStepInto/dotQualifiedInParam.kt +++ b/idea/testData/debugger/smartStepInto/dotQualifiedInParam.kt @@ -9,4 +9,4 @@ class A { fun f2(i: Int) {} -// EXISTS: f1(), f2(int) \ No newline at end of file +// EXISTS: f1(), f2(Int) \ No newline at end of file diff --git a/idea/testData/debugger/smartStepInto/funLiteral.kt b/idea/testData/debugger/smartStepInto/funLiteral.kt index 595f2ce508f..37fccf834dd 100644 --- a/idea/testData/debugger/smartStepInto/funLiteral.kt +++ b/idea/testData/debugger/smartStepInto/funLiteral.kt @@ -7,4 +7,4 @@ fun foo() { fun f1(f: () -> Unit) {} fun f2() {} -// EXISTS: f1(Function0), f1: f.invoke() \ No newline at end of file +// EXISTS: f1(() -> Unit), f1: f.invoke() \ No newline at end of file diff --git a/idea/testData/debugger/smartStepInto/infixCall.kt b/idea/testData/debugger/smartStepInto/infixCall.kt index 3e12514eb58..2b684eeaf6b 100644 --- a/idea/testData/debugger/smartStepInto/infixCall.kt +++ b/idea/testData/debugger/smartStepInto/infixCall.kt @@ -9,4 +9,4 @@ class A { fun f2(i: Int) {} -// EXISTS: f1(int), f2(int) \ No newline at end of file +// EXISTS: f1(Int), f2(Int) \ No newline at end of file diff --git a/idea/testData/debugger/smartStepInto/inlinedFunLiteral.kt b/idea/testData/debugger/smartStepInto/inlinedFunLiteral.kt index c5be7a28d75..d70aa96be26 100644 --- a/idea/testData/debugger/smartStepInto/inlinedFunLiteral.kt +++ b/idea/testData/debugger/smartStepInto/inlinedFunLiteral.kt @@ -4,4 +4,4 @@ fun foo() { inline fun f1(f: () -> Unit) {} -// EXISTS: f1(Function0) \ No newline at end of file +// EXISTS: f1(() -> Unit) \ No newline at end of file diff --git a/idea/testData/debugger/smartStepInto/multiline.kt b/idea/testData/debugger/smartStepInto/multiline.kt index 8091a6162d9..28b85a8c5f1 100644 --- a/idea/testData/debugger/smartStepInto/multiline.kt +++ b/idea/testData/debugger/smartStepInto/multiline.kt @@ -9,4 +9,4 @@ fun f1(vararg i: Int) {} fun f2() = 1 fun f3() = 1 -// EXISTS: f1(int...), f2(), f3() \ No newline at end of file +// EXISTS: f1(vararg Int), f2(), f3() \ No newline at end of file diff --git a/idea/testData/debugger/smartStepInto/param.kt b/idea/testData/debugger/smartStepInto/param.kt index 222ad3d7a0e..f6f879fc71d 100644 --- a/idea/testData/debugger/smartStepInto/param.kt +++ b/idea/testData/debugger/smartStepInto/param.kt @@ -5,4 +5,4 @@ fun foo() { fun f1(i: Int) = 1 fun f2() {} -// EXISTS: f1(int), f2() \ No newline at end of file +// EXISTS: f1(Int), f2() \ No newline at end of file diff --git a/idea/testData/debugger/smartStepInto/propertyGetter.kt b/idea/testData/debugger/smartStepInto/propertyGetter.kt index a836dee2a5d..ee0678c43a0 100644 --- a/idea/testData/debugger/smartStepInto/propertyGetter.kt +++ b/idea/testData/debugger/smartStepInto/propertyGetter.kt @@ -15,4 +15,4 @@ val d: Int return 1 } -// EXISTS: getC(), getD() \ No newline at end of file +// EXISTS: getter for c: Int, getter for d: Int \ No newline at end of file diff --git a/idea/testData/debugger/smartStepInto/renderer.kt b/idea/testData/debugger/smartStepInto/renderer.kt new file mode 100644 index 00000000000..e85683bbbd1 --- /dev/null +++ b/idea/testData/debugger/smartStepInto/renderer.kt @@ -0,0 +1,28 @@ +fun test() { + propFoo + foo() + fooWithParam(1.extFoo()) { 2 } + FooClass(1).test() + FooClass().test() + FooClass(1, 2).test() +} + +class FooClass(i: Int) { + constructor() : this(1) + constructor(i: Int, s: Int) : this(1) + + fun test() = 1 +} + +fun foo() = 1 +fun fooWithParam(i: Int, f: () -> Int) = 1 +fun Int.extFoo() = 1 + +val propFoo: Int + get() { + return 1 + } + +// EXISTS: getter for propFoo: Int, +// EXISTS: foo() +// EXISTS: fooWithParam(Int\, () -> Int) +// EXISTS: extFoo() +// EXISTS: fooWithParam: f.invoke() +// EXISTS: test() +// EXISTS: constructor FooClass() +// EXISTS: constructor FooClass(Int\, Int) \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractSmartStepIntoTest.kt b/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractSmartStepIntoTest.kt index e1d7336dae6..289935811fc 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractSmartStepIntoTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/AbstractSmartStepIntoTest.kt @@ -47,13 +47,15 @@ public abstract class AbstractSmartStepIntoTest : JetLightCodeInsightFixtureTest for (actualTargetName in actual) { assert(actualTargetName in expected) { - "Unexpected step into target was found: $actualTargetName\n${renderTableWithResults(expected, actual)}" + "Unexpected step into target was found: $actualTargetName\n${renderTableWithResults(expected, actual)}" + + "\n // EXISTS: ${actual.joinToString()}" } } for (expectedTargetName in expected) { assert(expectedTargetName in actual) { - "Missed step into target: $expectedTargetName\n${renderTableWithResults(expected, actual)}" + "Missed step into target: $expectedTargetName\n${renderTableWithResults(expected, actual)}" + + "\n // EXISTS: ${actual.joinToString()}" } } } @@ -62,8 +64,8 @@ public abstract class AbstractSmartStepIntoTest : JetLightCodeInsightFixtureTest val sb = StringBuilder() val maxExtStrSize = (expected.maxBy { it.length() }?.length() ?: 0) + 5 - val longerList = if (expected.size() < actual.size()) actual else expected - val shorterList = if (expected.size() < actual.size()) expected else actual + val longerList = (if (expected.size() < actual.size()) actual else expected).sort() + val shorterList = (if (expected.size() < actual.size()) expected else actual).sort() for ((i, element) in longerList.withIndex()) { sb.append(element) sb.append(" ".repeat(maxExtStrSize - element.length())) diff --git a/idea/tests/org/jetbrains/kotlin/idea/debugger/SmartStepIntoTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/debugger/SmartStepIntoTestGenerated.java index 5de5b55a4e2..55a51c3dd33 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/debugger/SmartStepIntoTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/debugger/SmartStepIntoTestGenerated.java @@ -161,6 +161,12 @@ public class SmartStepIntoTestGenerated extends AbstractSmartStepIntoTest { doTest(fileName); } + @TestMetadata("renderer.kt") + public void testRenderer() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/smartStepInto/renderer.kt"); + doTest(fileName); + } + @TestMetadata("simple.kt") public void testSimple() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/debugger/smartStepInto/simple.kt");