Debugger: Do not validate line breakpoints for irrelevant classes (KT-30714)
This commit is contained in:
+10
-3
@@ -29,6 +29,7 @@ import com.intellij.psi.search.GlobalSearchScope
|
|||||||
import com.intellij.util.containers.ConcurrentFactoryMap
|
import com.intellij.util.containers.ConcurrentFactoryMap
|
||||||
import com.sun.jdi.Location
|
import com.sun.jdi.Location
|
||||||
import com.sun.jdi.ReferenceType
|
import com.sun.jdi.ReferenceType
|
||||||
|
import com.sun.jdi.VirtualMachine
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches
|
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches
|
||||||
import org.jetbrains.kotlin.idea.refactoring.getLineCount
|
import org.jetbrains.kotlin.idea.refactoring.getLineCount
|
||||||
@@ -329,6 +330,12 @@ private fun inlinedLinesNumbers(
|
|||||||
|
|
||||||
@Volatile var emulateDexDebugInTests: Boolean = false
|
@Volatile var emulateDexDebugInTests: Boolean = false
|
||||||
|
|
||||||
fun DebugProcess.isDexDebug() =
|
fun DebugProcess.isDexDebug(): Boolean {
|
||||||
(emulateDexDebugInTests && ApplicationManager.getApplication().isUnitTestMode) ||
|
val virtualMachine = (this.virtualMachineProxy as? VirtualMachineProxyImpl)?.virtualMachine
|
||||||
(this.virtualMachineProxy as? VirtualMachineProxyImpl)?.virtualMachine?.name() == "Dalvik" // TODO: check other machine names
|
return virtualMachine.isDexDebug()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun VirtualMachine?.isDexDebug(): Boolean {
|
||||||
|
// TODO: check other machine names
|
||||||
|
return (emulateDexDebugInTests && ApplicationManager.getApplication().isUnitTestMode) || this?.name() == "Dalvik"
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.debugger.breakpoints
|
||||||
|
|
||||||
|
import com.intellij.debugger.engine.DebugProcess
|
||||||
|
import com.intellij.debugger.impl.DebuggerUtilsEx
|
||||||
|
import com.intellij.debugger.ui.breakpoints.LineBreakpoint
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.xdebugger.XSourcePosition
|
||||||
|
import com.intellij.xdebugger.breakpoints.XBreakpoint
|
||||||
|
import com.intellij.xdebugger.breakpoints.XBreakpointProperties
|
||||||
|
import com.sun.jdi.AbsentInformationException
|
||||||
|
import com.sun.jdi.ReferenceType
|
||||||
|
import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.KOTLIN_STRATA_NAME
|
||||||
|
import org.jetbrains.kotlin.idea.debugger.isDexDebug
|
||||||
|
|
||||||
|
class KotlinLineBreakpoint(
|
||||||
|
project: Project?,
|
||||||
|
xBreakpoint: XBreakpoint<out XBreakpointProperties<*>>?
|
||||||
|
) : LineBreakpoint<JavaLineBreakpointProperties>(project, xBreakpoint) {
|
||||||
|
override fun processClassPrepare(debugProcess: DebugProcess?, classType: ReferenceType?) {
|
||||||
|
val sourcePosition = xBreakpoint?.sourcePosition
|
||||||
|
|
||||||
|
if (classType != null && sourcePosition != null) {
|
||||||
|
if (!hasTargetLine(classType, sourcePosition)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.processClassPrepare(debugProcess, classType)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns false if `classType` definitely does not contain a location for a given `sourcePosition`.
|
||||||
|
*/
|
||||||
|
private fun hasTargetLine(classType: ReferenceType, sourcePosition: XSourcePosition): Boolean {
|
||||||
|
val allLineLocations = DebuggerUtilsEx.allLineLocations(classType) ?: return true
|
||||||
|
|
||||||
|
if (classType.virtualMachine().isDexDebug()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
val fileName = sourcePosition.file.name
|
||||||
|
val lineNumber = sourcePosition.line + 1
|
||||||
|
|
||||||
|
for (location in allLineLocations) {
|
||||||
|
try {
|
||||||
|
val kotlinFileName = location.sourceName(KOTLIN_STRATA_NAME)
|
||||||
|
val kotlinLineNumber = location.lineNumber(KOTLIN_STRATA_NAME)
|
||||||
|
if (kotlinFileName == fileName && kotlinLineNumber == lineNumber) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} catch (e: AbsentInformationException) {
|
||||||
|
if (location.sourceName() == fileName && location.lineNumber() == lineNumber) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -45,6 +45,14 @@ public class KotlinLineBreakpointType extends JavaLineBreakpointType {
|
|||||||
super("kotlin-line", "Kotlin Line Breakpoints");
|
super("kotlin-line", "Kotlin Line Breakpoints");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Breakpoint<JavaLineBreakpointProperties> createJavaBreakpoint(
|
||||||
|
Project project, XBreakpoint<JavaLineBreakpointProperties> breakpoint
|
||||||
|
) {
|
||||||
|
return new KotlinLineBreakpoint(project, breakpoint);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matchesPosition(@NotNull LineBreakpoint<?> breakpoint, @NotNull SourcePosition position) {
|
public boolean matchesPosition(@NotNull LineBreakpoint<?> breakpoint, @NotNull SourcePosition position) {
|
||||||
JavaBreakpointProperties properties = getProperties(breakpoint);
|
JavaBreakpointProperties properties = getProperties(breakpoint);
|
||||||
|
|||||||
Reference in New Issue
Block a user