Debugger: refactor smart step into to use descriptors instead of psi elements (KT-13485)
#KT-13485 Fixed
This commit is contained in:
committed by
Nikolay Krasko
parent
f7203da2d6
commit
0fb5a18a26
@@ -50,9 +50,9 @@ import org.jetbrains.kotlin.idea.util.application.runReadAction
|
|||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.psi.KtParameter
|
|
||||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -116,9 +116,9 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
if (lambdaOrFunIfInside != null) {
|
if (lambdaOrFunIfInside != null) {
|
||||||
return SourcePosition.createFromElement(lambdaOrFunIfInside.bodyExpression!!)
|
return SourcePosition.createFromElement(lambdaOrFunIfInside.bodyExpression!!)
|
||||||
}
|
}
|
||||||
val property = getParameterIfInConstructor(location, psiFile, lineNumber)
|
val elementInDeclaration = getElementForDeclarationLine(location, psiFile, lineNumber)
|
||||||
if (property != null) {
|
if (elementInDeclaration != null) {
|
||||||
return SourcePosition.createFromElement(property)
|
return SourcePosition.createFromElement(elementInDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lineNumber > psiFile.getLineCount() && myDebugProcess.isDexDebug()) {
|
if (lineNumber > psiFile.getLineCount() && myDebugProcess.isDexDebug()) {
|
||||||
@@ -134,18 +134,25 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
return SourcePosition.createFromLine(psiFile, lineNumber)
|
return SourcePosition.createFromLine(psiFile, lineNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getParameterIfInConstructor(location: Location, file: KtFile, lineNumber: Int): KtParameter? {
|
// Returns a property or a constructor if debugger stops at class declaration
|
||||||
|
private fun getElementForDeclarationLine(location: Location, file: KtFile, lineNumber: Int): KtElement? {
|
||||||
val lineStartOffset = file.getLineStartOffset(lineNumber) ?: return null
|
val lineStartOffset = file.getLineStartOffset(lineNumber) ?: return null
|
||||||
val elementAt = file.findElementAt(lineStartOffset)
|
val elementAt = file.findElementAt(lineStartOffset)
|
||||||
val contextElement = KotlinCodeFragmentFactory.getContextElement(elementAt)
|
val contextElement = KotlinCodeFragmentFactory.getContextElement(elementAt)
|
||||||
|
|
||||||
|
if (contextElement !is KtClass) return null
|
||||||
|
|
||||||
val methodName = location.method().name()
|
val methodName = location.method().name()
|
||||||
if (contextElement is KtClass && JvmAbi.isGetterName(methodName)) {
|
return when {
|
||||||
val parameterForGetter = contextElement.getPrimaryConstructor()?.valueParameters?.firstOrNull() {
|
JvmAbi.isGetterName(methodName) -> {
|
||||||
it.hasValOrVar() && it.name != null && JvmAbi.getterName(it.name!!) == methodName
|
val parameterForGetter = contextElement.getPrimaryConstructor()?.valueParameters?.firstOrNull() {
|
||||||
} ?: return null
|
it.hasValOrVar() && it.name != null && JvmAbi.getterName(it.name!!) == methodName
|
||||||
return parameterForGetter
|
} ?: return null
|
||||||
|
parameterForGetter
|
||||||
|
}
|
||||||
|
methodName == "<init>" -> contextElement.getPrimaryConstructor()
|
||||||
|
else -> null
|
||||||
}
|
}
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLambdaOrFunIfInside(location: Location, file: KtFile, lineNumber: Int): KtFunction? {
|
private fun getLambdaOrFunIfInside(location: Location, file: KtFile, lineNumber: Int): KtFunction? {
|
||||||
|
|||||||
+38
-16
@@ -16,31 +16,31 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.debugger.stepping
|
package org.jetbrains.kotlin.idea.debugger.stepping
|
||||||
|
|
||||||
import com.intellij.debugger.SourcePosition
|
|
||||||
import com.intellij.debugger.engine.DebugProcessImpl
|
import com.intellij.debugger.engine.DebugProcessImpl
|
||||||
import com.intellij.debugger.engine.NamedMethodFilter
|
import com.intellij.debugger.engine.NamedMethodFilter
|
||||||
import com.intellij.debugger.impl.DebuggerUtilsEx
|
|
||||||
import com.intellij.util.Range
|
import com.intellij.util.Range
|
||||||
import com.sun.jdi.Location
|
import com.sun.jdi.Location
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.psi.KtAnonymousInitializer
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
import org.jetbrains.kotlin.psi.KtConstructor
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate
|
||||||
|
import org.jetbrains.kotlin.resolve.findTopMostOverriddenDescriptors
|
||||||
|
|
||||||
class KotlinBasicStepMethodFilter(
|
class KotlinBasicStepMethodFilter(
|
||||||
val resolvedElement: KtElement,
|
val descriptor: CallableDescriptor,
|
||||||
val myCallingExpressionLines: Range<Int>
|
val myCallingExpressionLines: Range<Int>
|
||||||
) : NamedMethodFilter {
|
) : NamedMethodFilter {
|
||||||
private val myTargetMethodName: String
|
private val myTargetMethodName: String
|
||||||
|
|
||||||
init {
|
init {
|
||||||
myTargetMethodName = when (resolvedElement) {
|
myTargetMethodName = when (descriptor) {
|
||||||
is KtAnonymousInitializer -> "<init>"
|
is ClassDescriptor, is ConstructorDescriptor -> "<init>"
|
||||||
is KtConstructor<*> -> "<init>"
|
is PropertyAccessorDescriptor -> JvmAbi.getterName(descriptor.correspondingProperty.name.asString())
|
||||||
is KtPropertyAccessor -> JvmAbi.getterName((resolvedElement.property).name!!)
|
else -> descriptor.name.asString()
|
||||||
else -> resolvedElement.name!!
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,13 +52,35 @@ class KotlinBasicStepMethodFilter(
|
|||||||
val method = location.method()
|
val method = location.method()
|
||||||
if (myTargetMethodName != method.name()) return false
|
if (myTargetMethodName != method.name()) return false
|
||||||
|
|
||||||
val sourcePosition = runReadAction { SourcePosition.createFromElement(resolvedElement) } ?: return false
|
|
||||||
val positionManager = process.positionManager ?: return false
|
val positionManager = process.positionManager ?: return false
|
||||||
|
|
||||||
val classes = positionManager.getAllClasses(sourcePosition)
|
val descriptor = runReadAction {
|
||||||
|
val elementAt = positionManager.getSourcePosition(location)?.elementAt
|
||||||
|
|
||||||
return classes.any {
|
val declaration = elementAt?.getParentOfTypesAndPredicate(false, KtDeclaration::class.java) {
|
||||||
it == location.declaringType() || DebuggerUtilsEx.isAssignableFrom(it.name(), location.declaringType())
|
it !is KtProperty || !it.isLocal
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaration is KtClass && method.name() == "<init>") {
|
||||||
|
(declaration.resolveToDescriptor() as? ClassDescriptor)?.unsubstitutedPrimaryConstructor
|
||||||
|
} else {
|
||||||
|
declaration?.resolveToDescriptor()
|
||||||
|
}
|
||||||
|
} ?: return false
|
||||||
|
|
||||||
|
fun compareDescriptors(d1: DeclarationDescriptor, d2: DeclarationDescriptor): Boolean {
|
||||||
|
return d1 == d2 || d1.original == d2.original
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (compareDescriptors(descriptor, this.descriptor)) return true
|
||||||
|
|
||||||
|
if (descriptor is CallableDescriptor) {
|
||||||
|
return descriptor.findTopMostOverriddenDescriptors().any { compareDescriptors(it, this.descriptor) } ||
|
||||||
|
this.descriptor.findTopMostOverriddenDescriptors().any { compareDescriptors(it, descriptor)}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+6
-6
@@ -3,23 +3,23 @@ package org.jetbrains.kotlin.idea.debugger.stepping
|
|||||||
import com.intellij.debugger.actions.SmartStepTarget
|
import com.intellij.debugger.actions.SmartStepTarget
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.util.Range
|
import com.intellij.util.Range
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
|
||||||
import org.jetbrains.kotlin.renderer.ParameterNameRenderingPolicy
|
import org.jetbrains.kotlin.renderer.ParameterNameRenderingPolicy
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||||
import javax.swing.Icon
|
import javax.swing.Icon
|
||||||
|
|
||||||
class KotlinMethodSmartStepTarget(
|
class KotlinMethodSmartStepTarget(
|
||||||
val resolvedElement: KtElement,
|
val descriptor: CallableDescriptor,
|
||||||
label: String,
|
label: String,
|
||||||
highlightElement: PsiElement,
|
highlightElement: PsiElement,
|
||||||
lines: Range<Int>
|
lines: Range<Int>
|
||||||
): SmartStepTarget(label, highlightElement, false, lines) {
|
): SmartStepTarget(label, highlightElement, false, lines) {
|
||||||
override fun getIcon(): Icon? {
|
override fun getIcon(): Icon? {
|
||||||
return when {
|
return when {
|
||||||
resolvedElement is KtNamedFunction && resolvedElement.receiverTypeReference != null -> KotlinIcons.EXTENSION_FUNCTION
|
descriptor.isExtension -> KotlinIcons.EXTENSION_FUNCTION
|
||||||
else -> KotlinIcons.FUNCTION
|
else -> KotlinIcons.FUNCTION
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,8 +43,8 @@ class KotlinMethodSmartStepTarget(
|
|||||||
|
|
||||||
if (other == null || other !is KotlinMethodSmartStepTarget) return false
|
if (other == null || other !is KotlinMethodSmartStepTarget) return false
|
||||||
|
|
||||||
return resolvedElement == other.resolvedElement
|
return descriptor == other.descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode() = resolvedElement.hashCode()
|
override fun hashCode() = descriptor.hashCode()
|
||||||
}
|
}
|
||||||
+22
-22
@@ -27,12 +27,14 @@ import com.intellij.util.Range
|
|||||||
import com.intellij.util.containers.OrderedSet
|
import com.intellij.util.containers.OrderedSet
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
|
import org.jetbrains.kotlin.load.java.isFromJava
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentCall
|
||||||
@@ -146,20 +148,15 @@ class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() {
|
|||||||
val delegatedResolvedCall = bindingContext[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor]
|
val delegatedResolvedCall = bindingContext[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor]
|
||||||
if (delegatedResolvedCall == null) {
|
if (delegatedResolvedCall == null) {
|
||||||
val getter = DescriptorToSourceUtilsIde.getAnyDeclaration(file.project, getterDescriptor)
|
val getter = DescriptorToSourceUtilsIde.getAnyDeclaration(file.project, getterDescriptor)
|
||||||
if (getter is KtPropertyAccessor && (getter.bodyExpression != null || getter.equalsToken != null)) {
|
if (getter is KtPropertyAccessor && getter.hasBody()) {
|
||||||
val label = KotlinMethodSmartStepTarget.calcLabel(getterDescriptor)
|
val label = KotlinMethodSmartStepTarget.calcLabel(getterDescriptor)
|
||||||
result.add(KotlinMethodSmartStepTarget(getter, label, expression, lines))
|
result.add(KotlinMethodSmartStepTarget(getterDescriptor, label, expression, lines))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val delegatedPropertyGetterDescriptor = delegatedResolvedCall.resultingDescriptor
|
val delegatedPropertyGetterDescriptor = delegatedResolvedCall.resultingDescriptor
|
||||||
if (delegatedPropertyGetterDescriptor is CallableMemberDescriptor) {
|
val label = "${propertyDescriptor.name}." + KotlinMethodSmartStepTarget.calcLabel(delegatedPropertyGetterDescriptor)
|
||||||
val function = DescriptorToSourceUtilsIde.getAnyDeclaration(file.project, delegatedPropertyGetterDescriptor)
|
result.add(KotlinMethodSmartStepTarget(delegatedPropertyGetterDescriptor, label, expression, lines))
|
||||||
if (function is KtNamedFunction || function is KtSecondaryConstructor) {
|
|
||||||
val label = "${propertyDescriptor.name}." + KotlinMethodSmartStepTarget.calcLabel(delegatedPropertyGetterDescriptor)
|
|
||||||
result.add(KotlinMethodSmartStepTarget(function as KtFunction, label, expression, lines))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,19 +169,22 @@ class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() {
|
|||||||
|
|
||||||
val descriptor = resolvedCall.resultingDescriptor
|
val descriptor = resolvedCall.resultingDescriptor
|
||||||
if (descriptor is FunctionDescriptor && !isIntrinsic(descriptor)) {
|
if (descriptor is FunctionDescriptor && !isIntrinsic(descriptor)) {
|
||||||
val resolvedElement = DescriptorToSourceUtilsIde.getAnyDeclaration(file.project, descriptor)
|
if (descriptor.isFromJava) {
|
||||||
if (resolvedElement is KtNamedFunction || resolvedElement is KtConstructor<*>) {
|
(DescriptorToSourceUtilsIde.getAnyDeclaration(file.project, descriptor) as? PsiMethod)?.let {
|
||||||
|
result.add(MethodSmartStepTarget(it, null, expression, false, lines))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (descriptor is ConstructorDescriptor && descriptor.isPrimary) {
|
||||||
|
val psiElement = DescriptorToSourceUtilsIde.getAnyDeclaration(file.project, descriptor)
|
||||||
|
if (psiElement is KtClass && psiElement.getAnonymousInitializers().isEmpty()) {
|
||||||
|
// There is no constructor or init block, so do not show it in smart step into
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val label = KotlinMethodSmartStepTarget.calcLabel(descriptor)
|
val label = KotlinMethodSmartStepTarget.calcLabel(descriptor)
|
||||||
result.add(KotlinMethodSmartStepTarget(resolvedElement as KtFunction, label, expression, lines))
|
result.add(KotlinMethodSmartStepTarget(descriptor, label, expression, 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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ 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.resolvedElement, stepTarget.callingExpressionLines!!)
|
is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget.descriptor, stepTarget.callingExpressionLines!!)
|
||||||
is KotlinLambdaSmartStepTarget -> KotlinLambdaMethodFilter(stepTarget.getLambda(), stepTarget.callingExpressionLines!!, stepTarget.isInline)
|
is KotlinLambdaSmartStepTarget -> KotlinLambdaMethodFilter(stepTarget.getLambda(), stepTarget.callingExpressionLines!!, stepTarget.isInline)
|
||||||
else -> super.createMethodFilter(stepTarget)
|
else -> super.createMethodFilter(stepTarget)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,30 +9,36 @@ LineBreakpoint created at smartStepIntoConstructor.kt:35
|
|||||||
LineBreakpoint created at smartStepIntoConstructor.kt:39
|
LineBreakpoint created at smartStepIntoConstructor.kt:39
|
||||||
LineBreakpoint created at smartStepIntoConstructor.kt:43
|
LineBreakpoint created at smartStepIntoConstructor.kt:43
|
||||||
LineBreakpoint created at smartStepIntoConstructor.kt:47
|
LineBreakpoint created at smartStepIntoConstructor.kt:47
|
||||||
|
LineBreakpoint created at smartStepIntoConstructor.kt:51
|
||||||
|
LineBreakpoint created at smartStepIntoConstructor.kt:55
|
||||||
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! smartStepIntoConstructor.SmartStepIntoConstructorKt
|
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! smartStepIntoConstructor.SmartStepIntoConstructorKt
|
||||||
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
smartStepIntoConstructor.kt:7
|
smartStepIntoConstructor.kt:7
|
||||||
smartStepIntoConstructor.kt:51
|
smartStepIntoConstructor.kt:59
|
||||||
smartStepIntoConstructor.kt:11
|
smartStepIntoConstructor.kt:11
|
||||||
smartStepIntoConstructor.kt:52
|
smartStepIntoConstructor.kt:60
|
||||||
smartStepIntoConstructor.kt:15
|
smartStepIntoConstructor.kt:15
|
||||||
smartStepIntoConstructor.kt:54
|
smartStepIntoConstructor.kt:62
|
||||||
smartStepIntoConstructor.kt:19
|
smartStepIntoConstructor.kt:19
|
||||||
smartStepIntoConstructor.kt:57
|
smartStepIntoConstructor.kt:65
|
||||||
smartStepIntoConstructor.kt:23
|
smartStepIntoConstructor.kt:23
|
||||||
smartStepIntoConstructor.kt:61
|
|
||||||
smartStepIntoConstructor.kt:27
|
|
||||||
smartStepIntoConstructor.kt:66
|
|
||||||
smartStepIntoConstructor.kt:31
|
|
||||||
smartStepIntoConstructor.kt:69
|
smartStepIntoConstructor.kt:69
|
||||||
smartStepIntoConstructor.kt:35
|
smartStepIntoConstructor.kt:27
|
||||||
smartStepIntoConstructor.kt:74
|
smartStepIntoConstructor.kt:74
|
||||||
|
smartStepIntoConstructor.kt:31
|
||||||
|
smartStepIntoConstructor.kt:77
|
||||||
|
smartStepIntoConstructor.kt:35
|
||||||
|
smartStepIntoConstructor.kt:82
|
||||||
smartStepIntoConstructor.kt:39
|
smartStepIntoConstructor.kt:39
|
||||||
smartStepIntoConstructor.kt:81
|
|
||||||
smartStepIntoConstructor.kt:43
|
|
||||||
smartStepIntoConstructor.kt:89
|
smartStepIntoConstructor.kt:89
|
||||||
smartStepIntoConstructor.kt:47
|
smartStepIntoConstructor.kt:43
|
||||||
smartStepIntoConstructor.kt:97
|
smartStepIntoConstructor.kt:97
|
||||||
|
smartStepIntoConstructor.kt:47
|
||||||
|
smartStepIntoConstructor.kt:105
|
||||||
|
smartStepIntoConstructor.kt:51
|
||||||
|
smartStepIntoConstructor.kt:112
|
||||||
|
smartStepIntoConstructor.kt:55
|
||||||
|
smartStepIntoConstructor.kt:113
|
||||||
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
Process finished with exit code 0
|
Process finished with exit code 0
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
LineBreakpoint created at smartStepIntoInterfaceFun.kt:23
|
||||||
|
LineBreakpoint created at smartStepIntoInterfaceFun.kt:27
|
||||||
|
!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!KOTLIN_RUNTIME!;!CUSTOM_LIBRARY!;!RT_JAR! smartStepIntoInterfaceFun.SmartStepIntoInterfaceFunKt
|
||||||
|
Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
smartStepIntoInterfaceFun.kt:23
|
||||||
|
smartStepIntoInterfaceFun.kt:11
|
||||||
|
smartStepIntoInterfaceFun.kt:27
|
||||||
|
smartStepIntoInterfaceFun.kt:14
|
||||||
|
Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket'
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
|
|
||||||
|
|
||||||
+12
@@ -45,6 +45,14 @@ fun main(args: Array<String>) {
|
|||||||
// RESUME: 1
|
// RESUME: 1
|
||||||
//Breakpoint!
|
//Breakpoint!
|
||||||
N(1)
|
N(1)
|
||||||
|
// SMART_STEP_INTO_BY_INDEX: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
O(1)
|
||||||
|
// SMART_STEP_INTO_BY_INDEX: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
O(1, "1")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,4 +108,8 @@ class N {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
class O<T>(i: T) {
|
||||||
|
constructor(i: Int, j: T): this(j) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
// KT-13485
|
||||||
|
package smartStepIntoInterfaceFun
|
||||||
|
|
||||||
|
interface ObjectFace<T> {
|
||||||
|
fun act()
|
||||||
|
fun act2(t: T)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ObjectClass : ObjectFace<Int> {
|
||||||
|
override fun act() {
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
override fun act2(t: Int) {
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
val simple: ObjectFace<Int> = ObjectClass()
|
||||||
|
// SMART_STEP_INTO_BY_INDEX: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
simple.act()
|
||||||
|
// SMART_STEP_INTO_BY_INDEX: 1
|
||||||
|
// RESUME: 1
|
||||||
|
//Breakpoint!
|
||||||
|
simple.act2(1)
|
||||||
|
}
|
||||||
@@ -55,6 +55,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
|||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils.findStringWithPrefixes
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.lang.AssertionError
|
||||||
import javax.swing.SwingUtilities
|
import javax.swing.SwingUtilities
|
||||||
|
|
||||||
abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
||||||
@@ -213,7 +214,7 @@ abstract class KotlinDebuggerTestBase : KotlinDebuggerTestCase() {
|
|||||||
stepTarget ->
|
stepTarget ->
|
||||||
when (stepTarget) {
|
when (stepTarget) {
|
||||||
is KotlinLambdaSmartStepTarget -> KotlinLambdaMethodFilter(stepTarget.getLambda(), stepTarget.getCallingExpressionLines()!!, stepTarget.isInline)
|
is KotlinLambdaSmartStepTarget -> KotlinLambdaMethodFilter(stepTarget.getLambda(), stepTarget.getCallingExpressionLines()!!, stepTarget.isInline)
|
||||||
is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget.resolvedElement, stepTarget.getCallingExpressionLines()!!)
|
is KotlinMethodSmartStepTarget -> KotlinBasicStepMethodFilter(stepTarget.descriptor, stepTarget.getCallingExpressionLines()!!)
|
||||||
is MethodSmartStepTarget -> BasicStepMethodFilter(stepTarget.method, stepTarget.getCallingExpressionLines())
|
is MethodSmartStepTarget -> BasicStepMethodFilter(stepTarget.method, stepTarget.getCallingExpressionLines())
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -890,6 +890,12 @@ public class KotlinSteppingTestGenerated extends AbstractKotlinSteppingTest {
|
|||||||
doCustomTest(fileName);
|
doCustomTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("smartStepIntoInterfaceFun.kt")
|
||||||
|
public void testSmartStepIntoInterfaceFun() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/smartStepIntoInterfaceFun.kt");
|
||||||
|
doCustomTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("smartStepIntoInterfaceImpl.kt")
|
@TestMetadata("smartStepIntoInterfaceImpl.kt")
|
||||||
public void testSmartStepIntoInterfaceImpl() throws Exception {
|
public void testSmartStepIntoInterfaceImpl() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/smartStepIntoInterfaceImpl.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/debugger/tinyApp/src/stepping/custom/smartStepIntoInterfaceImpl.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user