mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
[debugger] IDEA-347829 Notify that debugger waits for smart mode in the progress bar
fixup! Move creation of prepare request back to DebuggerManagerThread fixup! [debugger] IDEA-347829 Notify that debugger waits for smart mode in the progress bar fixup! [debugger] IDEA-347829 Notify that debugger waits for smart mode in the progress bar do not catch PCE fixup! [debugger] IDEA-347829 Notify that debugger waits for smart mode in the progress bar [debugger] IDEA-347829 Notify that debugger waits for smart mode in the progress bar Merge-request: IJ-MR-127990 Merged-by: Maksim Zuev <Maksim.Zuev@jetbrains.com> GitOrigin-RevId: 95377a480739b31ef2e9fbc305760b765beffb46
This commit is contained in:
committed by
intellij-monorepo-bot
parent
af582866f0
commit
1cd746276d
@@ -44,4 +44,7 @@ property.watchpoint.add.dialog.title=Add Property Watchpoint
|
||||
property.watchpoint.add.dialog.choose.owner.class.title=Choose Property Owner Class
|
||||
property.watchpoint.add.dialog.choose.owner.class.label=Fully qualified name of a class:
|
||||
property.watchpoint.add.dialog.choose.property.label=Property name:
|
||||
property.watchpoint.add.dialog.chooser.title={0,choice, 0#Class Has No Properties|1#Select Property}
|
||||
property.watchpoint.add.dialog.chooser.title={0,choice, 0#Class Has No Properties|1#Select Property}
|
||||
|
||||
progress.title.installing.kotlin.breakpoint=Installing Kotlin breakpoint
|
||||
progress.text.waiting.for.smart.mode=Waiting for indexing to complete
|
||||
@@ -3,6 +3,7 @@
|
||||
// The package directive doesn't match the file location to prevent API breakage
|
||||
package org.jetbrains.kotlin.idea.debugger
|
||||
|
||||
import com.intellij.concurrency.ContextAwareRunnable
|
||||
import com.intellij.debugger.MultiRequestPositionManager
|
||||
import com.intellij.debugger.NoDataException
|
||||
import com.intellij.debugger.SourcePosition
|
||||
@@ -19,12 +20,17 @@ 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.ReadAction
|
||||
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.ProcessCanceledException
|
||||
import com.intellij.openapi.progress.runBlockingCancellable
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.platform.ide.progress.withBackgroundProgress
|
||||
import com.intellij.platform.util.progress.withProgressText
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiManager
|
||||
@@ -42,6 +48,7 @@ import com.intellij.xdebugger.frame.XStackFrame
|
||||
import com.intellij.xdebugger.impl.XDebugSessionImpl
|
||||
import com.sun.jdi.*
|
||||
import com.sun.jdi.request.ClassPrepareRequest
|
||||
import kotlinx.coroutines.*
|
||||
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.analyze
|
||||
import org.jetbrains.kotlin.analysis.api.calls.successfulFunctionCallOrNull
|
||||
@@ -72,7 +79,7 @@ import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
class KotlinPositionManager(private val debugProcess: DebugProcess) : MultiRequestPositionManager, PositionManagerWithMultipleStackFrames {
|
||||
private val sourceSearchScopes: List<GlobalSearchScope> = listOf(
|
||||
@@ -611,34 +618,54 @@ class KotlinPositionManager(private val debugProcess: DebugProcess) : MultiReque
|
||||
}
|
||||
|
||||
val isInsideProjectWithCompose = position.isInsideProjectWithCompose()
|
||||
var nonBlocking = ReadAction.nonBlocking<List<ClassPrepareRequest>> {
|
||||
val kotlinRequests = createKotlinClassPrepareRequests(requestor, position)
|
||||
if (isInsideProjectWithCompose) {
|
||||
val singletonRequest = getClassPrepareRequestForComposableSingletons(debugProcess, requestor, file)
|
||||
if (singletonRequest == null)
|
||||
kotlinRequests
|
||||
else
|
||||
kotlinRequests + singletonRequest
|
||||
val xBreakpoint = requestor.asSafely<Breakpoint<*>>()?.xBreakpoint
|
||||
val xSession = debugProcess.asSafely<DebugProcessImpl>()?.xdebugProcess?.session.asSafely<XDebugSessionImpl>()
|
||||
return runBlockingCancellable {
|
||||
if (xBreakpoint == null || xSession == null) {
|
||||
collectPrepareRequestPatterns(requestor, position, isInsideProjectWithCompose, file)
|
||||
} else {
|
||||
kotlinRequests
|
||||
cancelIfExpired({ readAction { xSession.isBreakpointActive(xBreakpoint) } }) {
|
||||
collectPrepareRequestPatterns(requestor, position, isInsideProjectWithCompose, file)
|
||||
}
|
||||
}
|
||||
}.mapNotNull { pattern -> debugProcess.requestsManager.createClassPrepareRequest(requestor, pattern) }
|
||||
}
|
||||
|
||||
private suspend fun collectPrepareRequestPatterns(
|
||||
requestor: ClassPrepareRequestor,
|
||||
position: SourcePosition,
|
||||
isInsideProjectWithCompose: Boolean,
|
||||
file: KtFile
|
||||
): List<String> {
|
||||
val project = debugProcess.project
|
||||
return withBackgroundProgress(
|
||||
project, KotlinDebuggerCoreBundle.message("progress.title.installing.kotlin.breakpoint"),
|
||||
cancellable = false
|
||||
) {
|
||||
withProgressText(KotlinDebuggerCoreBundle.message("progress.text.waiting.for.smart.mode")) {
|
||||
waitForSmartMode(project)
|
||||
}
|
||||
smartReadAction(project) {
|
||||
doCollectPrepareRequestPatterns(requestor, position, isInsideProjectWithCompose, file)
|
||||
}
|
||||
}
|
||||
.inSmartMode(debugProcess.project)
|
||||
}
|
||||
|
||||
val xBreakpoint = requestor.safeAs<Breakpoint<*>>()?.xBreakpoint
|
||||
val xSession = debugProcess.asSafely<DebugProcessImpl>()?.xdebugProcess?.session.asSafely<XDebugSessionImpl>()
|
||||
if (xBreakpoint != null && xSession != null) {
|
||||
nonBlocking = nonBlocking.expireWhen { !xSession.isBreakpointActive(xBreakpoint) }
|
||||
}
|
||||
try {
|
||||
return nonBlocking.executeSynchronously()
|
||||
} catch (_: ProcessCanceledException) {
|
||||
return emptyList()
|
||||
private fun doCollectPrepareRequestPatterns(
|
||||
requestor: ClassPrepareRequestor, position: SourcePosition,
|
||||
isInsideProjectWithCompose: Boolean, file: KtFile
|
||||
): List<String> {
|
||||
val kotlinRequests = getKotlinClassPrepareRequestPatterns(requestor, position)
|
||||
return if (isInsideProjectWithCompose) {
|
||||
val singletonRequest = getClassPrepareRequestPatternForComposableSingletons(file)
|
||||
kotlinRequests + singletonRequest
|
||||
} else {
|
||||
kotlinRequests
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresReadLock
|
||||
private fun createKotlinClassPrepareRequests(requestor: ClassPrepareRequestor, position: SourcePosition): List<ClassPrepareRequest> {
|
||||
private fun getKotlinClassPrepareRequestPatterns(requestor: ClassPrepareRequestor, position: SourcePosition): List<String> {
|
||||
val refinedPosition = when (requestor) {
|
||||
is SourcePositionRefiner -> requestor.refineSourcePosition(position)
|
||||
else -> position
|
||||
@@ -646,12 +673,7 @@ class KotlinPositionManager(private val debugProcess: DebugProcess) : MultiReque
|
||||
|
||||
return ClassNameProvider(debugProcess.project, debugProcess.searchScope, ClassNameProvider.Configuration.DEFAULT)
|
||||
.getCandidates(refinedPosition)
|
||||
.flatMap { name ->
|
||||
listOfNotNull(
|
||||
debugProcess.requestsManager.createClassPrepareRequest(requestor, name),
|
||||
debugProcess.requestsManager.createClassPrepareRequest(requestor, "$name$*")
|
||||
)
|
||||
}
|
||||
.flatMap { name -> listOf(name, "$name$*") }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -773,3 +795,32 @@ private class IrLambdaDescriptor(name: String) : Comparable<IrLambdaDescriptor>
|
||||
return lambdaId.size - other.lambdaId.size
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun <T> CoroutineScope.cancelIfExpired(condition: suspend () -> Boolean, action: suspend () -> T): T {
|
||||
val cancellationJob = cancelWhenExpired(this, condition)
|
||||
try {
|
||||
return action()
|
||||
} finally {
|
||||
cancellationJob.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun cancelWhenExpired(scope: CoroutineScope, condition: suspend () -> Boolean): Job {
|
||||
suspend fun checkExpired() {
|
||||
if (!condition()) {
|
||||
scope.cancel()
|
||||
}
|
||||
}
|
||||
checkExpired()
|
||||
return scope.launch {
|
||||
while (true) {
|
||||
checkExpired()
|
||||
delay(500)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace with platform implementation when IJPL-805 is fixed
|
||||
private suspend fun waitForSmartMode(project: Project) = suspendCancellableCoroutine {
|
||||
DumbService.getInstance(project).runWhenSmart(ContextAwareRunnable { it.resume(Unit) })
|
||||
}
|
||||
|
||||
@@ -3,12 +3,10 @@ package org.jetbrains.kotlin.idea.debugger.core
|
||||
|
||||
import com.intellij.debugger.SourcePosition
|
||||
import com.intellij.debugger.engine.DebugProcess
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor
|
||||
import com.intellij.openapi.application.ReadAction
|
||||
import com.intellij.openapi.application.runReadAction
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.sun.jdi.ReferenceType
|
||||
import com.sun.jdi.request.ClassPrepareRequest
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
@@ -56,13 +54,5 @@ fun getComposableSingletonsClasses(debugProcess: DebugProcess, file: KtFile): Li
|
||||
}
|
||||
}
|
||||
|
||||
fun getClassPrepareRequestForComposableSingletons(
|
||||
debugProcess: DebugProcess,
|
||||
requestor: ClassPrepareRequestor,
|
||||
file: KtFile
|
||||
): ClassPrepareRequest? {
|
||||
return debugProcess.requestsManager.createClassPrepareRequest(
|
||||
requestor,
|
||||
"${computeComposableSingletonsClassName(file)}\$*"
|
||||
)
|
||||
}
|
||||
fun getClassPrepareRequestPatternForComposableSingletons(file: KtFile): String =
|
||||
"${computeComposableSingletonsClassName(file)}\$*"
|
||||
|
||||
Reference in New Issue
Block a user