mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[debugger] IDEA-363091 Introduce coroutinized getSourcePositionAsync
GitOrigin-RevId: 461f361cbfdfc6dbca70411db168395ab62d8cdc
This commit is contained in:
committed by
intellij-monorepo-bot
parent
7b2aeecdf4
commit
bdc85458e4
@@ -10,16 +10,20 @@ import com.intellij.debugger.engine.evaluation.EvaluationContext
|
||||
import com.intellij.debugger.impl.DebuggerUtilsAsync
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx
|
||||
import com.intellij.debugger.impl.DebuggerUtilsImpl
|
||||
import com.intellij.debugger.impl.suppressExceptions
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl
|
||||
import com.intellij.execution.filters.LineNumbersMapping
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.fileTypes.FileType
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager
|
||||
import com.intellij.openapi.fileTypes.UnknownFileType
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.blockingContext
|
||||
import com.intellij.openapi.progress.checkCanceled
|
||||
import com.intellij.util.ThreeState
|
||||
import com.intellij.xdebugger.frame.XStackFrame
|
||||
import com.sun.jdi.Location
|
||||
@@ -52,21 +56,23 @@ class CompoundPositionManager() : PositionManagerWithConditionEvaluation, MultiR
|
||||
mySourcePositionCache.clear()
|
||||
}
|
||||
|
||||
private fun <T> iterate(position: SourcePosition, defaultValue: T?, processor: (PositionManager) -> T?): T? {
|
||||
private inline fun <T> iterate(position: SourcePosition, defaultValue: T?, processor: (PositionManager) -> T?): T? {
|
||||
val fileType = position.getFile().getFileType()
|
||||
return iterate<T>(defaultValue, fileType, true, processor)
|
||||
return iterate<T>(defaultValue, fileType, true, ProgressManager::checkCanceled, processor)
|
||||
}
|
||||
|
||||
private fun <T> iterate(defaultValue: T?, fileType: FileType?, ignorePCE: Boolean, processor: (PositionManager) -> T?): T? {
|
||||
private inline fun <T> iterate(
|
||||
defaultValue: T?, fileType: FileType?, ignorePCE: Boolean,
|
||||
cancellationCheck: () -> Unit,
|
||||
processor: (PositionManager) -> T?,
|
||||
): T? {
|
||||
for (positionManager in myPositionManagers) {
|
||||
if (!acceptsFileType(positionManager, fileType)) continue
|
||||
try {
|
||||
if (!ignorePCE) {
|
||||
ProgressManager.checkCanceled()
|
||||
cancellationCheck()
|
||||
}
|
||||
return DebuggerUtilsImpl.suppressExceptions<T?, NoDataException?>(
|
||||
{ processor(positionManager) },
|
||||
defaultValue, ignorePCE, NoDataException::class.java)
|
||||
return suppressExceptions(defaultValue, ignorePCE, NoDataException::class.java) { processor(positionManager) }
|
||||
}
|
||||
catch (_: NoDataException) {
|
||||
}
|
||||
@@ -74,68 +80,50 @@ class CompoundPositionManager() : PositionManagerWithConditionEvaluation, MultiR
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
private fun <T> iterateAsync(
|
||||
fileType: FileType?,
|
||||
ignorePCE: Boolean,
|
||||
processor: (PositionManager) -> CompletableFuture<T?>,
|
||||
): CompletableFuture<T?> {
|
||||
var res = CompletableFuture.failedFuture<T?>(NoDataException.INSTANCE)
|
||||
for (positionManager in myPositionManagers) {
|
||||
if (!acceptsFileType(positionManager, fileType)) continue
|
||||
res = res.exceptionallyCompose { e: Throwable ->
|
||||
val unwrap = DebuggerUtilsAsync.unwrap(e)
|
||||
if (unwrap is NoDataException) {
|
||||
if (!ignorePCE) {
|
||||
ProgressManager.checkCanceled()
|
||||
}
|
||||
return@exceptionallyCompose processor(positionManager)
|
||||
}
|
||||
CompletableFuture.failedFuture<T?>(unwrap)
|
||||
}
|
||||
}
|
||||
return res
|
||||
fun getSourcePositionFuture(location: Location?): CompletableFuture<SourcePosition?> = invokeCommandAsCompletableFuture {
|
||||
getSourcePositionAsync(location)
|
||||
}
|
||||
|
||||
override fun getSourcePositionAsync(location: Location?): CompletableFuture<SourcePosition?> =
|
||||
getCachedSourcePosition(location) { fileType: FileType? ->
|
||||
iterateAsync<SourcePosition?>(fileType, false) { getSourcePositionAsync(it, location) }
|
||||
override suspend fun getSourcePositionAsync(location: Location?): SourcePosition? =
|
||||
getCachedSourcePosition(location, { action -> readAction(action) }) { fileType: FileType? ->
|
||||
iterate<SourcePosition?>(null, fileType, false, { checkCanceled() }) { getSourcePositionAsync(it, location) }
|
||||
}
|
||||
|
||||
private fun getCachedSourcePosition(
|
||||
override fun getSourcePosition(location: Location?): SourcePosition? =
|
||||
getCachedSourcePosition(location, { action -> runReadAction(action) }) { fileType: FileType? ->
|
||||
ReadAction.nonBlocking<SourcePosition?> {
|
||||
iterate<SourcePosition?>(null, fileType, false, ProgressManager::checkCanceled) { it.getSourcePosition(location) }
|
||||
}.executeSynchronously()
|
||||
}
|
||||
|
||||
private inline fun getCachedSourcePosition(
|
||||
location: Location?,
|
||||
producer: (FileType?) -> CompletableFuture<SourcePosition?>,
|
||||
): CompletableFuture<SourcePosition?> {
|
||||
if (location == null) return CompletableFuture.completedFuture<SourcePosition?>(null)
|
||||
var res: SourcePosition? = null
|
||||
insideReadAction: (() -> Unit) -> Unit,
|
||||
producer: (FileType?) -> SourcePosition?,
|
||||
): SourcePosition? {
|
||||
if (location == null) return null
|
||||
try {
|
||||
res = mySourcePositionCache[location]
|
||||
val position = mySourcePositionCache[location]
|
||||
if (position != null && checkCacheEntry(position, location.declaringType().name(), insideReadAction)) {
|
||||
return position
|
||||
}
|
||||
}
|
||||
catch (_: IllegalArgumentException) { // Invalid method id
|
||||
}
|
||||
if (checkCacheEntry(res, location)) return CompletableFuture.completedFuture<SourcePosition?>(res)
|
||||
|
||||
val fileType = runReadAction {
|
||||
val sourceName = DebuggerUtilsEx.getSourceName(location, null)
|
||||
if (sourceName != null) FileTypeManager.getInstance().getFileTypeByFileName(sourceName) else null
|
||||
val sourceName = DebuggerUtilsEx.getSourceName(location, null)
|
||||
val fileType = if (sourceName != null)
|
||||
callInReadAction(insideReadAction) { FileTypeManager.getInstance().getFileTypeByFileName(sourceName) }
|
||||
else
|
||||
null
|
||||
|
||||
val position = producer(fileType)
|
||||
try {
|
||||
mySourcePositionCache.put(location, position)
|
||||
}
|
||||
return producer(fileType)
|
||||
.thenApply<SourcePosition?> { p: SourcePosition? ->
|
||||
try {
|
||||
mySourcePositionCache.put(location, p)
|
||||
}
|
||||
catch (_: IllegalArgumentException) { // Invalid method id
|
||||
}
|
||||
p
|
||||
}
|
||||
}
|
||||
|
||||
override fun getSourcePosition(location: Location?): SourcePosition? {
|
||||
return getCachedSourcePosition(location) { fileType: FileType? ->
|
||||
val sourcePosition = ReadAction.nonBlocking<SourcePosition?> {
|
||||
iterate<SourcePosition?>(null, fileType, false) { it.getSourcePosition(location) }
|
||||
}.executeSynchronously()
|
||||
CompletableFuture.completedFuture<SourcePosition?>(sourcePosition)
|
||||
}.getNow(null)
|
||||
catch (_: IllegalArgumentException) { // Invalid method id
|
||||
}
|
||||
return position
|
||||
}
|
||||
|
||||
override fun getAllClasses(classPosition: SourcePosition): MutableList<ReferenceType?> =
|
||||
@@ -173,7 +161,7 @@ class CompoundPositionManager() : PositionManagerWithConditionEvaluation, MultiR
|
||||
}!!
|
||||
|
||||
fun createStackFrames(descriptor: StackFrameDescriptorImpl): MutableList<XStackFrame>? =
|
||||
iterate(null, null, false) {
|
||||
iterate(null, null, false, ProgressManager::checkCanceled) {
|
||||
if (it is PositionManagerWithMultipleStackFrames) {
|
||||
val stackFrames = it.createStackFrames(descriptor)
|
||||
if (stackFrames != null) {
|
||||
@@ -222,26 +210,32 @@ private fun acceptsFileType(positionManager: PositionManager, fileType: FileType
|
||||
return types.contains(fileType)
|
||||
}
|
||||
|
||||
private fun getSourcePositionAsync(positionManager: PositionManager, location: Location?): CompletableFuture<SourcePosition?> {
|
||||
private suspend fun getSourcePositionAsync(positionManager: PositionManager, location: Location?): SourcePosition? {
|
||||
if (positionManager is PositionManagerAsync) {
|
||||
return positionManager.getSourcePositionAsync(location)
|
||||
}
|
||||
try {
|
||||
val sourcePosition = ReadAction.nonBlocking<SourcePosition?> { positionManager.getSourcePosition(location) }.executeSynchronously()
|
||||
return CompletableFuture.completedFuture<SourcePosition?>(sourcePosition)
|
||||
return blockingContext {
|
||||
ReadAction.nonBlocking<SourcePosition?> { positionManager.getSourcePosition(location) }.executeSynchronously()
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
return CompletableFuture.failedFuture<SourcePosition?>(DebuggerUtilsAsync.unwrap(e))
|
||||
throw DebuggerUtilsAsync.unwrap(e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkCacheEntry(position: SourcePosition?, location: Location): Boolean {
|
||||
if (position == null) return false
|
||||
return runReadAction {
|
||||
private inline fun checkCacheEntry(position: SourcePosition, className: String, insideReadAction: (() -> Unit) -> Unit): Boolean =
|
||||
callInReadAction(insideReadAction) {
|
||||
val psiFile = position.getFile()
|
||||
if (!psiFile.isValid()) return@runReadAction false
|
||||
val url = DebuggerUtilsEx.getAlternativeSourceUrl(location.declaringType().name(), psiFile.getProject()) ?: return@runReadAction true
|
||||
if (!psiFile.isValid()) return@callInReadAction false
|
||||
val url = DebuggerUtilsEx.getAlternativeSourceUrl(className, psiFile.getProject()) ?: return@callInReadAction true
|
||||
val file = psiFile.getVirtualFile()
|
||||
file != null && url == file.url
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private inline fun <T : Any?> callInReadAction(insideReadAction: (() -> Unit) -> Unit, crossinline action: () -> T): T {
|
||||
var result: T? = null
|
||||
insideReadAction { result = action() }
|
||||
return result as T
|
||||
}
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.debugger.engine
|
||||
|
||||
import com.intellij.debugger.PositionManager
|
||||
import com.intellij.debugger.SourcePosition
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.diagnostic.fileLogger
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.runBlockingMaybeCancellable
|
||||
import com.intellij.util.concurrency.annotations.RequiresBlockingContext
|
||||
import com.sun.jdi.Location
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.util.concurrent.CompletableFuture
|
||||
|
||||
@ApiStatus.Experimental
|
||||
interface PositionManagerAsync {
|
||||
fun getSourcePositionAsync(location: Location?): CompletableFuture<SourcePosition?>
|
||||
interface PositionManagerAsync : PositionManager {
|
||||
suspend fun getSourcePositionAsync(location: Location?): SourcePosition?
|
||||
|
||||
@RequiresBlockingContext
|
||||
override fun getSourcePosition(location: Location?): SourcePosition? {
|
||||
if (ApplicationManager.getApplication().isInternal
|
||||
&& ApplicationManager.getApplication().isReadAccessAllowed
|
||||
&& !ProgressManager.getInstance().hasProgressIndicator()) {
|
||||
fileLogger().error("Call runBlocking from read action without indicator")
|
||||
}
|
||||
return runBlockingMaybeCancellable {
|
||||
getSourcePositionAsync(location)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.debugger.impl
|
||||
|
||||
import com.intellij.openapi.diagnostic.fileLogger
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.sun.jdi.InternalException
|
||||
import com.sun.jdi.ObjectCollectedException
|
||||
import com.sun.jdi.VMDisconnectedException
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
inline fun <T, E : Exception> suppressExceptions(
|
||||
defaultValue: T?,
|
||||
ignorePCE: Boolean,
|
||||
rethrow: Class<E>? = null,
|
||||
supplier: () -> T?,
|
||||
): T? {
|
||||
try {
|
||||
return supplier()
|
||||
}
|
||||
catch (e: ProcessCanceledException) {
|
||||
if (!ignorePCE) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
catch (e: CancellationException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: VMDisconnectedException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: ObjectCollectedException) {
|
||||
throw e
|
||||
}
|
||||
catch (e: InternalException) {
|
||||
fileLogger().info(e)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
if (rethrow != null && rethrow.isInstance(e)) {
|
||||
throw e
|
||||
}
|
||||
else {
|
||||
fileLogger().error(e)
|
||||
}
|
||||
}
|
||||
catch (e: AssertionError) {
|
||||
if (rethrow != null && rethrow.isInstance(e)) {
|
||||
throw e
|
||||
}
|
||||
else {
|
||||
fileLogger().error(e)
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
@@ -530,7 +530,12 @@ public final class DebuggerUtilsAsync {
|
||||
}
|
||||
|
||||
public static Throwable unwrap(@Nullable Throwable throwable) {
|
||||
return throwable instanceof CompletionException || throwable instanceof ExecutionException ? throwable.getCause() : throwable;
|
||||
while (throwable instanceof CompletionException || throwable instanceof ExecutionException) {
|
||||
Throwable cause = throwable.getCause();
|
||||
if (cause == throwable) break;
|
||||
throwable = cause;
|
||||
}
|
||||
return throwable;
|
||||
}
|
||||
|
||||
public static <T> T logError(@NotNull Throwable throwable) {
|
||||
|
||||
@@ -249,40 +249,6 @@ public final class DebuggerUtilsImpl extends DebuggerUtilsEx {
|
||||
action.accept(wrapIntoThrowable ? new Throwable(e) : e);
|
||||
}
|
||||
|
||||
public static <T, E extends Exception> T suppressExceptions(ThrowableComputable<? extends T, ? extends E> supplier,
|
||||
T defaultValue) throws E {
|
||||
return suppressExceptions(supplier, defaultValue, true, null);
|
||||
}
|
||||
|
||||
public static <T, E extends Exception> T suppressExceptions(ThrowableComputable<? extends T, ? extends E> supplier,
|
||||
T defaultValue,
|
||||
boolean ignorePCE,
|
||||
Class<E> rethrow) throws E {
|
||||
try {
|
||||
return supplier.compute();
|
||||
}
|
||||
catch (ProcessCanceledException e) {
|
||||
if (!ignorePCE) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
catch (VMDisconnectedException | ObjectCollectedException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (InternalException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
catch (Exception | AssertionError e) {
|
||||
if (rethrow != null && rethrow.isInstance(e)) {
|
||||
throw e;
|
||||
}
|
||||
else {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static @NlsContexts.Label String getConnectionWaitStatus(@NotNull RemoteConnection connection) {
|
||||
String connectionName = ObjectUtils.doIfNotNull(connection, DebuggerUtilsImpl::getConnectionDisplayName);
|
||||
return connection instanceof RemoteConnectionStub
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac
|
||||
try {
|
||||
Location location = frame.location();
|
||||
CompoundPositionManager positionManager = frame.getVirtualMachine().getDebugProcess().getPositionManager();
|
||||
return positionManager.getSourcePositionAsync(location);
|
||||
return positionManager.getSourcePositionFuture(location);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return CompletableFuture.failedFuture(e);
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.intellij.debugger;
|
||||
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.util.concurrency.annotations.RequiresBlockingContext;
|
||||
import com.sun.jdi.Location;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import com.sun.jdi.request.ClassPrepareRequest;
|
||||
@@ -41,6 +42,7 @@ public interface PositionManager {
|
||||
* @throws NoDataException if the location is not in the code managed by this {@code PositionManager}
|
||||
*/
|
||||
@Nullable
|
||||
@RequiresBlockingContext
|
||||
SourcePosition getSourcePosition(@Nullable Location location) throws NoDataException;
|
||||
|
||||
/**
|
||||
|
||||
+13
-1
@@ -6,6 +6,7 @@ import com.intellij.debugger.NoDataException
|
||||
import com.intellij.debugger.PositionManager
|
||||
import com.intellij.debugger.SourcePosition
|
||||
import com.intellij.debugger.engine.DebugProcess.JAVA_STRATUM
|
||||
import com.intellij.debugger.engine.PositionManagerAsync
|
||||
import com.intellij.debugger.engine.evaluation.AbsentInformationEvaluateException
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
|
||||
@@ -15,6 +16,7 @@ import com.intellij.debugger.jdi.LocalVariableProxyImpl
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
||||
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl
|
||||
import com.intellij.util.concurrency.annotations.RequiresBlockingContext
|
||||
import com.sun.jdi.*
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.kotlin.idea.debugger.base.util.KotlinDebuggerConstants.KOTLIN_STRATA_NAME
|
||||
@@ -136,11 +138,21 @@ fun ValueDescriptorImpl.safeCalcValue(context: EvaluationContextImpl): Value? {
|
||||
return wrapEvaluateException { calcValue(context) }
|
||||
}
|
||||
|
||||
@RequiresBlockingContext
|
||||
@ApiStatus.Internal
|
||||
fun PositionManager.safeGetSourcePosition(location: Location): SourcePosition? {
|
||||
return try {
|
||||
getSourcePosition(location)
|
||||
} catch (ex: NoDataException) {
|
||||
} catch (_: NoDataException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
suspend fun PositionManagerAsync.safeGetSourcePositionAsync(location: Location): SourcePosition? {
|
||||
return try {
|
||||
getSourcePositionAsync(location)
|
||||
} catch (_: NoDataException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
+1
-19
@@ -17,12 +17,10 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor
|
||||
import com.intellij.debugger.ui.breakpoints.Breakpoint
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.openapi.application.smartReadAction
|
||||
import com.intellij.openapi.fileTypes.FileType
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.runBlockingMaybeCancellable
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -125,23 +123,7 @@ class KotlinPositionManager(private val debugProcess: DebugProcess) : MultiReque
|
||||
return listOf(KotlinStackFrame(descriptor, visibleVariables))
|
||||
}
|
||||
|
||||
override fun getSourcePositionAsync(location: Location?): CompletableFuture<SourcePosition?> =
|
||||
invokeCommandAsCompletableFuture {
|
||||
getSourcePositionInternal(location)
|
||||
}
|
||||
|
||||
override fun getSourcePosition(location: Location?): SourcePosition? {
|
||||
if (ApplicationManager.getApplication().isInternal
|
||||
&& ApplicationManager.getApplication().isReadAccessAllowed
|
||||
&& !ProgressManager.getInstance().hasProgressIndicator()) {
|
||||
LOG.error("Call runBlocking from read action without indicator")
|
||||
}
|
||||
return runBlockingMaybeCancellable {
|
||||
getSourcePositionInternal(location)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getSourcePositionInternal(location: Location?): SourcePosition? {
|
||||
override suspend fun getSourcePositionAsync(location: Location?): SourcePosition? {
|
||||
DebuggerManagerThreadImpl.assertIsManagerThread()
|
||||
if (location == null) throw NoDataException.INSTANCE
|
||||
|
||||
|
||||
+6
-6
@@ -1,11 +1,11 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.kotlin.idea.debugger.stepping.smartStepInto
|
||||
|
||||
import com.intellij.debugger.PositionManager
|
||||
import com.intellij.debugger.engine.PositionManagerAsync
|
||||
import com.intellij.openapi.application.readAction
|
||||
import com.intellij.psi.util.parentOfType
|
||||
import com.sun.jdi.Location
|
||||
import org.jetbrains.kotlin.idea.debugger.base.util.safeGetSourcePosition
|
||||
import org.jetbrains.kotlin.idea.debugger.base.util.safeGetSourcePositionAsync
|
||||
import org.jetbrains.kotlin.idea.debugger.base.util.safeMethod
|
||||
import org.jetbrains.kotlin.idea.debugger.core.getInlineFunctionAndArgumentVariablesToBordersMap
|
||||
import org.jetbrains.kotlin.idea.debugger.core.isInlineFunctionMarkerVariableName
|
||||
@@ -60,7 +60,7 @@ internal class KotlinSmartStepTargetFiltererAdapter(
|
||||
|
||||
suspend fun visitTrace(
|
||||
targetFilterer: KotlinSmartStepTargetFilterer,
|
||||
positionManager: PositionManager
|
||||
positionManager: PositionManagerAsync
|
||||
): Pair<List<KotlinMethodSmartStepTarget>, List<KotlinMethodSmartStepTarget>> {
|
||||
for (element in visitedTrace) {
|
||||
visitTraceElement(element, targetFilterer, positionManager)
|
||||
@@ -76,7 +76,7 @@ internal class KotlinSmartStepTargetFiltererAdapter(
|
||||
private suspend fun visitTraceElement(
|
||||
element: BytecodeTraceElement,
|
||||
targetFilterer: KotlinSmartStepTargetFilterer,
|
||||
positionManager: PositionManager
|
||||
positionManager: PositionManagerAsync
|
||||
) {
|
||||
when (element) {
|
||||
is BytecodeTraceElement.InlineCall -> {
|
||||
@@ -122,7 +122,7 @@ private fun extractInlineCalls(location: Location): List<InlineCallInfo> = locat
|
||||
// Filter already visible variable to support smart-step-into while inside an inline function
|
||||
.filterNot { location.codeIndex() in it.bciRange }
|
||||
|
||||
private suspend fun getCalledInlineFunction(positionManager: PositionManager, location: Location): KtNamedFunction? {
|
||||
val sourcePosition = positionManager.safeGetSourcePosition(location) ?: return null
|
||||
private suspend fun getCalledInlineFunction(positionManager: PositionManagerAsync, location: Location): KtNamedFunction? {
|
||||
val sourcePosition = positionManager.safeGetSourcePositionAsync(location) ?: return null
|
||||
return readAction { sourcePosition.elementAt?.parentOfType<KtNamedFunction>() }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user