From 64f14ad89b0054aea16eb9cb84d3e35a58a96576 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 13 Jun 2018 17:20:35 +0300 Subject: [PATCH] Reformat: debugger.stepping --- .../stepping/DebugProcessImplHelper.java | 3 +- .../stepping/KotlinBasicStepMethodFilter.kt | 6 +- .../stepping/KotlinLambdaMethodFilter.kt | 17 +- .../KotlinLambdaSmartStepIntoTarget.kt | 12 +- .../KotlinMethodSmartStepIntoTarget.kt | 10 +- .../stepping/KotlinSimpleGetterProvider.kt | 5 +- .../stepping/KotlinSmartStepIntoHandler.kt | 28 +-- .../stepping/KotlinStepActionFactory.kt | 23 +- .../stepping/KotlinStepOverInlineFilter.kt | 10 +- .../KotlinStepOverInlinedLinesHint.kt | 23 +- .../stepping/KotlinSteppingCommandProvider.kt | 201 +++++++++--------- .../KotlinSuspendCallStepOverFilter.kt | 14 +- .../stepping/RequestHintWithMethodFilter.kt | 23 +- 13 files changed, 191 insertions(+), 184 deletions(-) diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/DebugProcessImplHelper.java b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/DebugProcessImplHelper.java index 7fbc7347422..f0ba961ce9c 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/DebugProcessImplHelper.java +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/DebugProcessImplHelper.java @@ -27,7 +27,8 @@ public class DebugProcessImplHelper { public static DebugProcessImpl.StepOverCommand createStepOverCommandWithCustomFilter( SuspendContextImpl suspendContext, boolean ignoreBreakpoints, - KotlinSuspendCallStepOverFilter methodFilter) { + KotlinSuspendCallStepOverFilter methodFilter + ) { DebugProcessImpl debugProcess = suspendContext.getDebugProcess(); return debugProcess.new StepOverCommand(suspendContext, ignoreBreakpoints, StepRequest.STEP_LINE) { @NotNull diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinBasicStepMethodFilter.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinBasicStepMethodFilter.kt index fbd2e9d1fa7..92020ccfbda 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinBasicStepMethodFilter.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinBasicStepMethodFilter.kt @@ -36,8 +36,8 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypesAndPredicate import org.jetbrains.kotlin.resolve.DescriptorUtils class KotlinBasicStepMethodFilter( - targetDescriptor: CallableMemberDescriptor, - private val myCallingExpressionLines: Range + targetDescriptor: CallableMemberDescriptor, + private val myCallingExpressionLines: Range ) : NamedMethodFilter { private val myTargetMethodName: String = when (targetDescriptor) { is ClassDescriptor, is ConstructorDescriptor -> "" @@ -46,7 +46,7 @@ class KotlinBasicStepMethodFilter( } private val _targetDescriptor = SofterReference( - (targetDescriptor as? FunctionDescriptor)?.let { SamCodegenUtil.getOriginalIfSamAdapter(it) } ?: targetDescriptor + (targetDescriptor as? FunctionDescriptor)?.let { SamCodegenUtil.getOriginalIfSamAdapter(it) } ?: targetDescriptor ) override fun getCallingExpressionLines() = myCallingExpressionLines diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinLambdaMethodFilter.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinLambdaMethodFilter.kt index 3a7944a3f9d..b478196709b 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinLambdaMethodFilter.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinLambdaMethodFilter.kt @@ -22,18 +22,18 @@ import com.intellij.debugger.engine.DebugProcessImpl import com.intellij.util.Range import com.sun.jdi.Location import org.jetbrains.kotlin.codegen.coroutines.DO_RESUME_METHOD_NAME -import org.jetbrains.kotlin.idea.refactoring.isMultiLine import org.jetbrains.kotlin.idea.debugger.isInsideInlineArgument +import org.jetbrains.kotlin.idea.refactoring.isMultiLine import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.util.OperatorNameConventions class KotlinLambdaMethodFilter( - private val lambda: KtFunction, - private val myCallingExpressionLines: Range, - private val isInline: Boolean, - private val isSuspend: Boolean -): BreakpointStepMethodFilter { + private val lambda: KtFunction, + private val myCallingExpressionLines: Range, + private val isInline: Boolean, + private val isSuspend: Boolean +) : BreakpointStepMethodFilter { private val myFirstStatementPosition: SourcePosition? private val myLastStatementLine: Int @@ -52,8 +52,7 @@ class KotlinLambdaMethodFilter( } myFirstStatementPosition = firstStatementPosition myLastStatementLine = if (lastStatementPosition != null) lastStatementPosition.line else -1 - } - else { + } else { myFirstStatementPosition = SourcePosition.createFromElement(lambda) myLastStatementLine = myFirstStatementPosition!!.line } @@ -78,7 +77,7 @@ class KotlinLambdaMethodFilter( if (isSuspend) { return name == DO_RESUME_METHOD_NAME } - + return name == OperatorNameConventions.INVOKE.asString() } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinLambdaSmartStepIntoTarget.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinLambdaSmartStepIntoTarget.kt index 62c965a032f..0cc5a4e3584 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinLambdaSmartStepIntoTarget.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinLambdaSmartStepIntoTarget.kt @@ -26,12 +26,12 @@ import org.jetbrains.kotlin.util.OperatorNameConventions import javax.swing.Icon class KotlinLambdaSmartStepTarget( - label: String, - highlightElement: KtFunction, - lines: Range, - val isInline: Boolean, - val isSuspend: Boolean -): SmartStepTarget(label, highlightElement, true, lines) { + label: String, + highlightElement: KtFunction, + lines: Range, + val isInline: Boolean, + val isSuspend: Boolean +) : SmartStepTarget(label, highlightElement, true, lines) { override fun getIcon(): Icon = KotlinIcons.LAMBDA fun getLambda() = highlightElement as KtFunction diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinMethodSmartStepIntoTarget.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinMethodSmartStepIntoTarget.kt index 3ff5d7ad904..29f4660a8b3 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinMethodSmartStepIntoTarget.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinMethodSmartStepIntoTarget.kt @@ -13,11 +13,11 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import javax.swing.Icon class KotlinMethodSmartStepTarget( - val descriptor: CallableMemberDescriptor, - label: String, - highlightElement: PsiElement, - lines: Range -): SmartStepTarget(label, highlightElement, false, lines) { + val descriptor: CallableMemberDescriptor, + label: String, + highlightElement: PsiElement, + lines: Range +) : SmartStepTarget(label, highlightElement, false, lines) { override fun getIcon(): Icon? { return when { descriptor.isExtension -> KotlinIcons.EXTENSION_FUNCTION diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSimpleGetterProvider.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSimpleGetterProvider.kt index c4f5f146041..4986b27d590 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSimpleGetterProvider.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSimpleGetterProvider.kt @@ -32,13 +32,12 @@ class KotlinSimpleGetterProvider : SimplePropertyGetterProvider { if (accessor != null && accessor.isGetter) { val body = accessor.bodyExpression return when (body) { - // val a: Int get() { return field } is KtBlockExpression -> { + // val a: Int get() { return field } val returnedExpression = (body.statements.singleOrNull() as? KtReturnExpression)?.returnedExpression ?: return false returnedExpression.textMatches("field") } - // val a: Int get() = field - is KtExpression -> body.textMatches("field") + is KtExpression -> body.textMatches("field") // val a: Int get() = field else -> false } } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSmartStepIntoHandler.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSmartStepIntoHandler.kt index 8df1932dd0f..414e88e0157 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSmartStepIntoHandler.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSmartStepIntoHandler.kt @@ -54,8 +54,8 @@ class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { val elementAtOffset = position.elementAt ?: return emptyList() - val element = CodeInsightUtils.getTopmostElementAtOffset(elementAtOffset, elementAtOffset.textRange.startOffset) as? KtElement ?: - return emptyList() + val element = CodeInsightUtils.getTopmostElementAtOffset(elementAtOffset, elementAtOffset.textRange.startOffset) as? KtElement + ?: return emptyList() val elementTextRange = element.textRange ?: return emptyList() @@ -67,7 +67,7 @@ class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { val result = OrderedSet() // TODO support class initializers, local functions, delegated properties with specified type, setter for properties - element.accept(object: KtTreeVisitorVoid() { + element.accept(object : KtTreeVisitorVoid() { override fun visitLambdaExpression(lambdaExpression: KtLambdaExpression) { recordFunctionLiteral(lambdaExpression.functionLiteral) } @@ -87,8 +87,11 @@ class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { if (argument.arguments.any { getArgumentExpression(it) == function }) { val resultingDescriptor = resolvedCall.resultingDescriptor val label = KotlinLambdaSmartStepTarget.calcLabel(resultingDescriptor, param.name) - result.add(KotlinLambdaSmartStepTarget( - label, function, lines, InlineUtil.isInline(resultingDescriptor), param.type.isSuspendFunctionType)) + result.add( + KotlinLambdaSmartStepTarget( + label, function, lines, InlineUtil.isInline(resultingDescriptor), param.type.isSuspendFunctionType + ) + ) return true } } @@ -96,7 +99,8 @@ class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { return false } - private fun getArgumentExpression(it: ValueArgument) = (it.getArgumentExpression() as? KtLambdaExpression)?.functionLiteral ?: it.getArgumentExpression() + private fun getArgumentExpression(it: ValueArgument) = + (it.getArgumentExpression() as? KtLambdaExpression)?.functionLiteral ?: it.getArgumentExpression() override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression) { // skip calls in object declarations @@ -159,10 +163,10 @@ class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { val label = KotlinMethodSmartStepTarget.calcLabel(getterDescriptor) result.add(KotlinMethodSmartStepTarget(getterDescriptor, label, expression, lines)) } - } - else { + } else { val delegatedPropertyGetterDescriptor = delegatedResolvedCall.resultingDescriptor - val label = "${propertyDescriptor.name}." + KotlinMethodSmartStepTarget.calcLabel(delegatedPropertyGetterDescriptor) + val label = + "${propertyDescriptor.name}." + KotlinMethodSmartStepTarget.calcLabel(delegatedPropertyGetterDescriptor) result.add(KotlinMethodSmartStepTarget(delegatedPropertyGetterDescriptor, label, expression, lines)) } } @@ -180,8 +184,7 @@ class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { (DescriptorToSourceUtilsIde.getAnyDeclaration(file.project, descriptor) as? PsiMethod)?.let { result.add(MethodSmartStepTarget(it, null, expression, false, lines)) } - } - else { + } else { if (descriptor is ConstructorDescriptor && descriptor.isPrimary) { val psiElement = DescriptorToSourceUtilsIde.getAnyDeclaration(file.project, descriptor) if (psiElement is KtClass && psiElement.getAnonymousInitializers().isEmpty()) { @@ -216,7 +219,8 @@ class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() { KotlinBasicStepMethodFilter(stepTarget.descriptor, stepTarget.callingExpressionLines!!) is KotlinLambdaSmartStepTarget -> KotlinLambdaMethodFilter( - stepTarget.getLambda(), stepTarget.callingExpressionLines!!, stepTarget.isInline, stepTarget.isSuspend) + stepTarget.getLambda(), stepTarget.callingExpressionLines!!, stepTarget.isInline, stepTarget.isSuspend + ) else -> super.createMethodFilter(stepTarget) } } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepActionFactory.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepActionFactory.kt index 75b18fa2995..b65c77ce8fe 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepActionFactory.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepActionFactory.kt @@ -61,13 +61,15 @@ class KotlinStepActionFactory(private val debuggerProcess: DebugProcessImpl) { // TODO: ask for better API // Should be safe to use reflection as method is protected and not obfuscated private fun doStep( - suspendContext: SuspendContextImpl, - stepThread: ThreadReferenceProxyImpl, - size: Int, depth: Int, hint: RequestHint) { + suspendContext: SuspendContextImpl, + stepThread: ThreadReferenceProxyImpl, + size: Int, depth: Int, hint: RequestHint + ) { val doStepMethod = DebugProcessImpl::class.java.getDeclaredMethod( - "doStep", - SuspendContextImpl::class.java, ThreadReferenceProxyImpl::class.java, - Integer.TYPE, Integer.TYPE, RequestHint::class.java) + "doStep", + SuspendContextImpl::class.java, ThreadReferenceProxyImpl::class.java, + Integer.TYPE, Integer.TYPE, RequestHint::class.java + ) doStepMethod.isAccessible = true @@ -89,7 +91,8 @@ class KotlinStepActionFactory(private val debuggerProcess: DebugProcessImpl) { return field.get(debuggerProcess) as T } - private inner class StepOverInlineCommand(private val mySmartStepFilter: KotlinMethodFilter, private val myStepSize: Int) : KotlinStepAction() { + private inner class StepOverInlineCommand(private val mySmartStepFilter: KotlinMethodFilter, private val myStepSize: Int) : + KotlinStepAction() { private fun getContextThread(suspendContext: SuspendContextImpl): ThreadReferenceProxyImpl? { val contextThread = debuggerContext.threadProxy return contextThread ?: suspendContext.thread @@ -114,8 +117,7 @@ class KotlinStepActionFactory(private val debuggerProcess: DebugProcessImpl) { } if (isResumeOnlyCurrentThread && suspendContext.suspendPolicy == EventRequest.SUSPEND_ALL) { suspendManager.resumeThread(suspendContext, thread) - } - else { + } else { suspendManager.resume(suspendContext) } } @@ -136,8 +138,7 @@ class KotlinStepActionFactory(private val debuggerProcess: DebugProcessImpl) { try { session.setIgnoreStepFiltersFlag(stepThread.frameCount()) - } - catch (e: EvaluateException) { + } catch (e: EvaluateException) { LOG.info(e) } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlineFilter.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlineFilter.kt index 0cc12590a9a..c7db54e0ae4 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlineFilter.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlineFilter.kt @@ -25,11 +25,11 @@ import com.sun.jdi.Location import org.jetbrains.kotlin.idea.debugger.ktLocationInfo class StepOverFilterData( - val lineNumber: Int, - val stepOverLines: Set, - val inlineRangeVariables: List, - val isDexDebug: Boolean, - val skipAfterCodeIndex: Long = -1 + val lineNumber: Int, + val stepOverLines: Set, + val inlineRangeVariables: List, + val isDexDebug: Boolean, + val skipAfterCodeIndex: Long = -1 ) class KotlinStepOverInlineFilter(val project: Project, val data: StepOverFilterData) : KotlinMethodFilter { diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlinedLinesHint.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlinedLinesHint.kt index 0bb67a28e9e..22e03f4ec28 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlinedLinesHint.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinStepOverInlinedLinesHint.kt @@ -16,22 +16,20 @@ package org.jetbrains.kotlin.idea.debugger.stepping -import com.intellij.debugger.SourcePosition -import com.intellij.debugger.engine.* +import com.intellij.debugger.engine.RequestHint +import com.intellij.debugger.engine.SuspendContextImpl import com.intellij.debugger.engine.evaluation.EvaluateException -import com.intellij.debugger.engine.jdi.StackFrameProxy import com.intellij.debugger.jdi.ThreadReferenceProxyImpl -import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.diagnostic.Logger -import com.intellij.openapi.util.Computable import com.sun.jdi.VMDisconnectedException import com.sun.jdi.request.StepRequest // Originally copied from RequestHint class KotlinStepOverInlinedLinesHint( - stepThread: ThreadReferenceProxyImpl, - suspendContext: SuspendContextImpl, - methodFilter: KotlinMethodFilter) : RequestHint(stepThread, suspendContext, methodFilter) { + stepThread: ThreadReferenceProxyImpl, + suspendContext: SuspendContextImpl, + methodFilter: KotlinMethodFilter +) : RequestHint(stepThread, suspendContext, methodFilter) { private val LOG = Logger.getInstance(KotlinStepOverInlinedLinesHint::class.java) @@ -46,8 +44,7 @@ class KotlinStepOverInlinedLinesHint( if (isTheSameFrame(context)) { return if (filter.locationMatches(context, frameProxy.location())) { STOP - } - else { + } else { StepRequest.STEP_OVER } } @@ -58,10 +55,8 @@ class KotlinStepOverInlinedLinesHint( return StepRequest.STEP_OUT } - } - catch (ignored: VMDisconnectedException) { - } - catch (e: EvaluateException) { + } catch (ignored: VMDisconnectedException) { + } catch (e: EvaluateException) { LOG.error(e) } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSteppingCommandProvider.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSteppingCommandProvider.kt index a59848ae344..908c5a8c515 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSteppingCommandProvider.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSteppingCommandProvider.kt @@ -62,9 +62,9 @@ import org.jetbrains.kotlin.utils.keysToMap class KotlinSteppingCommandProvider : JvmSteppingCommandProvider() { override fun getStepOverCommand( - suspendContext: SuspendContextImpl?, - ignoreBreakpoints: Boolean, - stepSize: Int + suspendContext: SuspendContextImpl?, + ignoreBreakpoints: Boolean, + stepSize: Int ): DebugProcessImpl.ResumeCommand? { if (suspendContext == null || suspendContext.isResumed) return null @@ -74,17 +74,18 @@ class KotlinSteppingCommandProvider : JvmSteppingCommandProvider() { @TestOnly fun getStepOverCommand( - suspendContext: SuspendContextImpl, - ignoreBreakpoints: Boolean, - debuggerContext: DebuggerContextImpl + suspendContext: SuspendContextImpl, + ignoreBreakpoints: Boolean, + debuggerContext: DebuggerContextImpl ): DebugProcessImpl.ResumeCommand? { return getStepOverCommand(suspendContext, ignoreBreakpoints, debuggerContext.sourcePosition) } private fun getStepOverCommand( - suspendContext: SuspendContextImpl, - ignoreBreakpoints: Boolean, - sourcePosition: SourcePosition): DebugProcessImpl.ResumeCommand? { + suspendContext: SuspendContextImpl, + ignoreBreakpoints: Boolean, + sourcePosition: SourcePosition + ): DebugProcessImpl.ResumeCommand? { val kotlinSourcePosition = KotlinSourcePosition.create(sourcePosition) ?: return null if (isSpecialStepOverNeeded(kotlinSourcePosition)) { @@ -95,14 +96,17 @@ class KotlinSteppingCommandProvider : JvmSteppingCommandProvider() { val location = suspendContext.debugProcess.invokeInManagerThread { suspendContext.frameProxy?.location() } ?: return null if (isInSuspendMethod(location) && !isOnSuspendReturnOrReenter(location) && !isLastLineLocationInMethod(location)) { return DebugProcessImplHelper.createStepOverCommandWithCustomFilter( - suspendContext, ignoreBreakpoints, KotlinSuspendCallStepOverFilter(sourcePosition.line, file, ignoreBreakpoints)) + suspendContext, ignoreBreakpoints, KotlinSuspendCallStepOverFilter(sourcePosition.line, file, ignoreBreakpoints) + ) } return null } - data class KotlinSourcePosition(val file: KtFile, val function: KtNamedFunction, - val linesRange: IntRange, val sourcePosition: SourcePosition) { + data class KotlinSourcePosition( + val file: KtFile, val function: KtNamedFunction, + val linesRange: IntRange, val sourcePosition: SourcePosition + ) { companion object { fun create(sourcePosition: SourcePosition): KotlinSourcePosition? { val file = sourcePosition.file as? KtFile ?: return null @@ -110,8 +114,8 @@ class KotlinSteppingCommandProvider : JvmSteppingCommandProvider() { val elementAt = sourcePosition.elementAt ?: return null val containingFunction = elementAt.parents - .filterIsInstance() - .firstOrNull { !it.isLocal } ?: return null + .filterIsInstance() + .firstOrNull { !it.isLocal } ?: return null val startLineNumber = containingFunction.getLineNumber(true) + 1 val endLineNumber = containingFunction.getLineNumber(false) + 1 @@ -193,14 +197,18 @@ private fun getInlineFunctionsIfAny(file: KtFile, offset: Int): List): List { return inlineFunctionCalls.flatMap { it.valueArguments - .map(::getArgumentExpression) - .filterIsInstance() + .map(::getArgumentExpression) + .filterIsInstance() } } -private fun getArgumentExpression(it: ValueArgument) = (it.getArgumentExpression() as? KtLambdaExpression)?.functionLiteral ?: it.getArgumentExpression() +private fun getArgumentExpression(it: ValueArgument) = + (it.getArgumentExpression() as? KtLambdaExpression)?.functionLiteral ?: it.getArgumentExpression() -private fun getInlineArgumentsCallsIfAny(sourcePosition: SourcePosition, declarationDescriptor: DeclarationDescriptor): List? { +private fun getInlineArgumentsCallsIfAny( + sourcePosition: SourcePosition, + declarationDescriptor: DeclarationDescriptor +): List? { if (declarationDescriptor !is CallableDescriptor) return null val valueParameters = declarationDescriptor.valueParameters.filter { it.type.isFunctionType }.toSet() @@ -249,12 +257,11 @@ private fun findCallsOnPosition(sourcePosition: SourcePosition, filter: (KtCallE val start = lineElement.startOffset val end = lineElement.endOffset - val allFilteredCalls = CodeInsightUtils. - findElementsOfClassInRange(file, start, end, KtExpression::class.java) - .map { KtPsiUtil.getParentCallIfPresent(it as KtExpression) } - .filterIsInstance() - .filter { filter(it) } - .toSet() + val allFilteredCalls = CodeInsightUtils.findElementsOfClassInRange(file, start, end, KtExpression::class.java) + .map { KtPsiUtil.getParentCallIfPresent(it as KtExpression) } + .filterIsInstance() + .filter { filter(it) } + .toSet() // It is necessary to check range because of multiline assign var linesRange = lineNumber..lineNumber @@ -267,16 +274,20 @@ private fun findCallsOnPosition(sourcePosition: SourcePosition, filter: (KtCallE } } -sealed class Action(val position: XSourcePositionImpl? = null, - val stepOverInlineData: StepOverFilterData? = null) { +sealed class Action( + val position: XSourcePositionImpl? = null, + val stepOverInlineData: StepOverFilterData? = null +) { class STEP_OVER : Action() { override fun apply(debugProcess: DebugProcessImpl, suspendContext: SuspendContextImpl, ignoreBreakpoints: Boolean) = - debugProcess.createStepOverCommand(suspendContext, ignoreBreakpoints).contextAction(suspendContext) + debugProcess.createStepOverCommand(suspendContext, ignoreBreakpoints).contextAction(suspendContext) } + class STEP_OUT : Action() { override fun apply(debugProcess: DebugProcessImpl, suspendContext: SuspendContextImpl, ignoreBreakpoints: Boolean) = debugProcess.createStepOutCommand(suspendContext).contextAction(suspendContext) } + class RUN_TO_CURSOR(position: XSourcePositionImpl) : Action(position) { override fun apply(debugProcess: DebugProcessImpl, suspendContext: SuspendContextImpl, ignoreBreakpoints: Boolean) { return runReadAction { @@ -284,10 +295,12 @@ sealed class Action(val position: XSourcePositionImpl? = null, }.contextAction(suspendContext) } } + class STEP_OVER_INLINED(stepOverInlineData: StepOverFilterData) : Action(stepOverInlineData = stepOverInlineData) { override fun apply(debugProcess: DebugProcessImpl, suspendContext: SuspendContextImpl, ignoreBreakpoints: Boolean) { return KotlinStepActionFactory(debugProcess).createKotlinStepOverInlineAction( - KotlinStepOverInlineFilter(debugProcess.project, stepOverInlineData!!)).contextAction(suspendContext) + KotlinStepOverInlineFilter(debugProcess.project, stepOverInlineData!!) + ).contextAction(suspendContext) } } @@ -299,26 +312,28 @@ interface KotlinMethodFilter : MethodFilter { } fun getStepOverAction( - location: Location, - kotlinSourcePosition: KotlinSteppingCommandProvider.KotlinSourcePosition, - frameProxy: StackFrameProxyImpl, - isDexDebug: Boolean + location: Location, + kotlinSourcePosition: KotlinSteppingCommandProvider.KotlinSourcePosition, + frameProxy: StackFrameProxyImpl, + isDexDebug: Boolean ): Action { val inlineArgumentsToSkip = runReadAction { getInlineCallFunctionArgumentsIfAny(kotlinSourcePosition.sourcePosition) } - return getStepOverAction(location, kotlinSourcePosition.file, kotlinSourcePosition.linesRange, - inlineArgumentsToSkip, frameProxy, isDexDebug) + return getStepOverAction( + location, kotlinSourcePosition.file, kotlinSourcePosition.linesRange, + inlineArgumentsToSkip, frameProxy, isDexDebug + ) } fun getStepOverAction( - location: Location, - sourceFile: KtFile, - range: IntRange, - inlineFunctionArguments: List, - frameProxy: StackFrameProxyImpl, - isDexDebug: Boolean + location: Location, + sourceFile: KtFile, + range: IntRange, + inlineFunctionArguments: List, + frameProxy: StackFrameProxyImpl, + isDexDebug: Boolean ): Action { location.declaringType() ?: return Action.STEP_OVER() @@ -346,19 +361,18 @@ fun getStepOverAction( try { return nextLocation.ktFileName() == sourceFile.name - } - catch(e: AbsentInformationException) { + } catch (e: AbsentInformationException) { return true } } fun isBackEdgeLocation(): Boolean { val previousSuitableLocation = methodLocations.reversed() - .dropWhile { it != location } - .drop(1) - .filter(::isThisMethodLocation) - .dropWhile { it.ktLineNumber() == location.ktLineNumber() } - .firstOrNull() + .dropWhile { it != location } + .drop(1) + .filter(::isThisMethodLocation) + .dropWhile { it.ktLineNumber() == location.ktLineNumber() } + .firstOrNull() return previousSuitableLocation != null && previousSuitableLocation.ktLineNumber() > location.ktLineNumber() } @@ -366,10 +380,9 @@ fun getStepOverAction( val patchedLocation = if (isBackEdgeLocation()) { // Pretend we had already done a backing step methodLocations - .filter(::isThisMethodLocation) - .firstOrNull { it.ktLineNumber() == location.ktLineNumber() } ?: location - } - else { + .filter(::isThisMethodLocation) + .firstOrNull { it.ktLineNumber() == location.ktLineNumber() } ?: location + } else { location } @@ -394,12 +407,12 @@ fun getStepOverAction( // We might erroneously extend this range too much when there's a call of function argument or other // inline function in last statement of inline function. The list of inlineRangeVariables will be used later to overcome it. val stepOverLocations = methodLocations - .dropWhile { it != patchedLocation } - .drop(1) - .dropWhile { it.ktLineNumber() == patchedLineNumber } - .takeWhile { loc -> - !isThisMethodLocation(loc) || lambdaArgumentRanges.any { loc.ktLineNumber() in it } || loc.ktLineNumber() == patchedLineNumber - } + .dropWhile { it != patchedLocation } + .drop(1) + .dropWhile { it.ktLineNumber() == patchedLineNumber } + .takeWhile { loc -> + !isThisMethodLocation(loc) || lambdaArgumentRanges.any { loc.ktLineNumber() in it } || loc.ktLineNumber() == patchedLineNumber + } if (!stepOverLocations.isEmpty()) { // Some Kotlin inlined methods with 'for' (and maybe others) generates bytecode that after dexing have a strange artifact. @@ -412,39 +425,39 @@ fun getStepOverAction( val locationsOfLine = method.safeLocationsOfLine(range.last) if (locationsOfLine.isNotEmpty()) { locationsOfLine.map { it.codeIndex() }.max() ?: -1L - } - else { + } else { findReturnFromDexBytecode(location.method()) } - } - else -1L + } else -1L - return Action.STEP_OVER_INLINED(StepOverFilterData( + return Action.STEP_OVER_INLINED( + StepOverFilterData( patchedLineNumber, stepOverLocations.map { it.ktLineNumber() }.toSet(), inlineRangeVariables, isDexDebug, returnCodeIndex - )) + ) + ) } return Action.STEP_OVER() } fun getStepOutAction( - location: Location, - suspendContext: SuspendContextImpl, - inlineFunctions: List, - inlinedArgument: KtFunctionLiteral? + location: Location, + suspendContext: SuspendContextImpl, + inlineFunctions: List, + inlinedArgument: KtFunctionLiteral? ): Action { val computedReferenceType = location.declaringType() ?: return Action.STEP_OUT() val locations = computedReferenceType.safeAllLineLocations() val nextLineLocations = locations - .dropWhile { it != location } - .drop(1) - .filter { it.method() == location.method() } - .dropWhile { it.lineNumber() == location.lineNumber() } + .dropWhile { it != location } + .drop(1) + .filter { it.method() == location.method() } + .dropWhile { it.lineNumber() == location.lineNumber() } if (inlineFunctions.isNotEmpty()) { val position = suspendContext.getXPositionForStepOutFromInlineFunction(nextLineLocations, inlineFunctions) @@ -460,11 +473,10 @@ fun getStepOutAction( } private fun SuspendContextImpl.getXPositionForStepOutFromInlineFunction( - locations: List, - inlineFunctionsToSkip: List + locations: List, + inlineFunctionsToSkip: List ): XSourcePositionImpl? { - return getNextPositionWithFilter(locations) { - offset, elementAt -> + return getNextPositionWithFilter(locations) { offset, elementAt -> if (inlineFunctionsToSkip.any { it.textRange.contains(offset) }) { return@getNextPositionWithFilter true } @@ -474,27 +486,25 @@ private fun SuspendContextImpl.getXPositionForStepOutFromInlineFunction( } private fun SuspendContextImpl.getXPositionForStepOutFromInlinedArgument( - locations: List, - inlinedArgumentToSkip: KtFunctionLiteral + locations: List, + inlinedArgumentToSkip: KtFunctionLiteral ): XSourcePositionImpl? { - return getNextPositionWithFilter(locations) { - offset, _ -> + return getNextPositionWithFilter(locations) { offset, _ -> inlinedArgumentToSkip.textRange.contains(offset) } } private fun SuspendContextImpl.getNextPositionWithFilter( - locations: List, - skip: (Int, PsiElement) -> Boolean + locations: List, + skip: (Int, PsiElement) -> Boolean ): XSourcePositionImpl? { for (location in locations) { - val position = runReadAction l@ { + val position = runReadAction l@{ val sourcePosition = try { this.debugProcess.positionManager.getSourcePosition(location) - } - catch(e: NoDataException) { - null - } ?: return@l null + } catch (e: NoDataException) { + null + } ?: return@l null val file = sourcePosition.file as? KtFile ?: return@l null val elementAt = sourcePosition.elementAt ?: return@l null @@ -514,11 +524,11 @@ private fun SuspendContextImpl.getNextPositionWithFilter( fun getInlineRangeLocalVariables(stackFrame: StackFrameProxyImpl): List { return stackFrame.visibleVariables() - .filter { - val name = it.name() - name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) - } - .map { it.variable } + .filter { + val name = it.name() + name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) + } + .map { it.variable } } private fun getInlineArgumentIfAny(elementAt: PsiElement?): KtFunctionLiteral? { @@ -541,8 +551,7 @@ private fun findReturnFromDexBytecode(method: Method): Long { while (true) { if (method.locationOfCodeIndex(lastMethodCodeIndex + 1) != null) { lastMethodCodeIndex++ - } - else { + } else { break } } @@ -562,11 +571,9 @@ private fun findReturnFromDexBytecode(method: Method): Long { if (instruction == RETURN_VOID || instruction == RETURN || instruction == RETURN_WIDE || instruction == RETURN_OBJECT) { // Instruction found return returnIndex - } - else if (instruction == MOVE || instruction == GOTO) { + } else if (instruction == MOVE || instruction == GOTO) { // proceed - } - else { + } else { // Don't know the instruction and it's length. Abort. break } diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSuspendCallStepOverFilter.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSuspendCallStepOverFilter.kt index e69573702dd..384f3ef28b1 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSuspendCallStepOverFilter.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/KotlinSuspendCallStepOverFilter.kt @@ -33,9 +33,10 @@ import org.jetbrains.kotlin.idea.debugger.suspendFunctionFirstLineLocation import org.jetbrains.kotlin.idea.util.application.runReadAction class KotlinSuspendCallStepOverFilter( - private val line: Int, - private val file: PsiFile, - private val ignoreBreakpoints: Boolean) : MethodFilter { + private val line: Int, + private val file: PsiFile, + private val ignoreBreakpoints: Boolean +) : MethodFilter { override fun getCallingExpressionLines(): Range? = Range(line, line) override fun locationMatches(process: DebugProcessImpl, location: Location?): Boolean { @@ -66,10 +67,9 @@ private fun createRunToCursorBreakpoint(context: SuspendContextImpl, line: Int, } val runToCursorBreakpoint = - runReadAction { - DebuggerManagerEx.getInstanceEx(process.project).breakpointManager.addRunToCursorBreakpoint(position, ignoreBreakpoints) - } ?: - return + runReadAction { + DebuggerManagerEx.getInstanceEx(process.project).breakpointManager.addRunToCursorBreakpoint(position, ignoreBreakpoints) + } ?: return runToCursorBreakpoint.suspendPolicy = when { context.suspendPolicy == EventRequest.SUSPEND_EVENT_THREAD -> DebuggerSettings.SUSPEND_THREAD diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/RequestHintWithMethodFilter.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/RequestHintWithMethodFilter.kt index 34fe9ead0f5..cc86b3b53c4 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/RequestHintWithMethodFilter.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/debugger/stepping/RequestHintWithMethodFilter.kt @@ -29,13 +29,16 @@ import org.intellij.lang.annotations.MagicConstant import java.lang.reflect.Field internal class RequestHintWithMethodFilter( - stepThread: ThreadReferenceProxyImpl, - suspendContext: SuspendContextImpl, - @MagicConstant(intValues = longArrayOf( - StepRequest.STEP_INTO.toLong(), - StepRequest.STEP_OVER.toLong(), - StepRequest.STEP_OUT.toLong())) depth: Int, - methodFilter: MethodFilter + stepThread: ThreadReferenceProxyImpl, + suspendContext: SuspendContextImpl, + @MagicConstant( + intValues = longArrayOf( + StepRequest.STEP_INTO.toLong(), + StepRequest.STEP_OVER.toLong(), + StepRequest.STEP_OUT.toLong() + ) + ) depth: Int, + methodFilter: MethodFilter ) : RequestHint(stepThread, suspendContext, methodFilter) { private var targetMethodMatched = false @@ -71,11 +74,9 @@ internal class RequestHintWithMethodFilter( return filter.onReached(context, this) } } - } - catch (ignored: VMDisconnectedException) { + } catch (ignored: VMDisconnectedException) { return STOP - } - catch (e: EvaluateException) { + } catch (e: EvaluateException) { LOG.error(e) return STOP }