Search for Kotlin sources in project too in fallback scope
When debugging in Gradle or Maven we may miss debug scope completely, but still want to be responsible for building source positions for all Kotlin source files (other PositionManagers may produce unexpected results).
This commit is contained in:
@@ -20,7 +20,6 @@ import com.intellij.debugger.SourcePosition
|
||||
import com.intellij.debugger.engine.DebugProcess
|
||||
import com.intellij.debugger.engine.DebuggerUtils
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.sun.jdi.AbsentInformationException
|
||||
import com.sun.jdi.ReferenceType
|
||||
@@ -46,7 +45,6 @@ import java.util.*
|
||||
|
||||
class DebuggerClassNameProvider(
|
||||
private val debugProcess: DebugProcess,
|
||||
scopes: List<GlobalSearchScope>,
|
||||
val findInlineUseSites: Boolean = true,
|
||||
val alwaysReturnLambdaParentClass: Boolean = true
|
||||
) {
|
||||
@@ -71,7 +69,7 @@ class DebuggerClassNameProvider(
|
||||
}
|
||||
}
|
||||
|
||||
private val inlineUsagesSearcher = InlineCallableUsagesSearcher(debugProcess, scopes)
|
||||
private val inlineUsagesSearcher = InlineCallableUsagesSearcher(debugProcess)
|
||||
|
||||
/**
|
||||
* Returns classes in which the given line number *is* present.
|
||||
|
||||
+4
-5
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.idea.debugger.DebuggerClassNameProvider.Companion.ge
|
||||
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches
|
||||
import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches.ComputedClassNames
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage
|
||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
@@ -38,10 +39,7 @@ import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
|
||||
class InlineCallableUsagesSearcher(
|
||||
private val myDebugProcess: DebugProcess,
|
||||
val scopes: List<GlobalSearchScope>
|
||||
) {
|
||||
class InlineCallableUsagesSearcher(private val myDebugProcess: DebugProcess) {
|
||||
fun findInlinedCalls(
|
||||
declaration: KtDeclaration,
|
||||
bindingContext: BindingContext = KotlinDebuggerCaches.getOrCreateTypeMapper(declaration).bindingContext,
|
||||
@@ -102,7 +100,8 @@ class InlineCallableUsagesSearcher(
|
||||
private fun getScopeForInlineDeclarationUsages(inlineDeclaration: KtDeclaration): GlobalSearchScope {
|
||||
val virtualFile = runReadAction { inlineDeclaration.containingFile.virtualFile }
|
||||
return if (virtualFile != null && ProjectRootsUtil.isLibraryFile(myDebugProcess.project, virtualFile)) {
|
||||
GlobalSearchScope.union(scopes.toTypedArray())
|
||||
myDebugProcess.searchScope.uniteWith(
|
||||
KotlinSourceFilterScope.librarySources(GlobalSearchScope.allScope(myDebugProcess.project), myDebugProcess.project))
|
||||
}
|
||||
else {
|
||||
myDebugProcess.searchScope
|
||||
|
||||
@@ -26,9 +26,12 @@ import com.intellij.debugger.engine.evaluation.EvaluationContext
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.impl.compiled.ClsFileImpl
|
||||
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.util.ThreeState
|
||||
import com.intellij.xdebugger.frame.XStackFrame
|
||||
@@ -60,10 +63,24 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import com.intellij.debugger.engine.DebuggerUtils as JDebuggerUtils
|
||||
|
||||
class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiRequestPositionManager, PositionManagerEx() {
|
||||
private val allKotlinFilesScope =
|
||||
object : DelegatingGlobalSearchScope(
|
||||
KotlinSourceFilterScope.projectAndLibrariesSources(GlobalSearchScope.allScope(myDebugProcess.project), myDebugProcess.project)
|
||||
) {
|
||||
private val projectIndex = ProjectRootManager.getInstance(myDebugProcess.project).fileIndex
|
||||
private val scopeComparator =
|
||||
Comparator.comparing(projectIndex::isInSourceContent)
|
||||
.thenComparing(projectIndex::isInLibrarySource)
|
||||
.thenComparing { file1, file2 -> super.compare(file1, file2) }
|
||||
|
||||
private val scopes: List<GlobalSearchScope> = listOf(
|
||||
override fun compare(file1: VirtualFile, file2: VirtualFile): Int {
|
||||
return scopeComparator.compare(file1, file2)
|
||||
}
|
||||
}
|
||||
|
||||
private val sourceSearchScopes: List<GlobalSearchScope> = listOf(
|
||||
myDebugProcess.searchScope,
|
||||
KotlinSourceFilterScope.librarySources(GlobalSearchScope.allScope(myDebugProcess.project), myDebugProcess.project)
|
||||
allKotlinFilesScope
|
||||
)
|
||||
|
||||
override fun evaluateCondition(context: EvaluationContext, frame: StackFrameProxyImpl, location: Location, expression: String): ThreeState? {
|
||||
@@ -100,12 +117,12 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
||||
val javaClassName = JvmClassName.byInternalName(defaultInternalName(location))
|
||||
val project = myDebugProcess.project
|
||||
|
||||
val defaultPsiFile = DebuggerUtils.findSourceFileForClass(project, scopes, javaClassName, javaSourceFileName)
|
||||
val defaultPsiFile = DebuggerUtils.findSourceFileForClass(project, sourceSearchScopes, javaClassName, javaSourceFileName)
|
||||
if (defaultPsiFile != null) {
|
||||
return SourcePosition.createFromLine(defaultPsiFile, 0)
|
||||
}
|
||||
}
|
||||
catch(e: AbsentInformationException) {
|
||||
catch (e: AbsentInformationException) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
@@ -208,7 +225,7 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
||||
continue
|
||||
}
|
||||
|
||||
val internalClassNames = DebuggerClassNameProvider(myDebugProcess, scopes, alwaysReturnLambdaParentClass = false)
|
||||
val internalClassNames = DebuggerClassNameProvider(myDebugProcess, alwaysReturnLambdaParentClass = false)
|
||||
.getOuterClassNamesForElement(literal.firstChild)
|
||||
.classNames
|
||||
|
||||
@@ -257,7 +274,7 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
||||
|
||||
val project = myDebugProcess.project
|
||||
|
||||
return DebuggerUtils.findSourceFileForClass(project, scopes, className, sourceName)
|
||||
return DebuggerUtils.findSourceFileForClass(project, sourceSearchScopes, className, sourceName)
|
||||
}
|
||||
|
||||
private fun defaultInternalName(location: Location): String {
|
||||
@@ -271,7 +288,7 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
||||
val psiFile = sourcePosition.file
|
||||
if (psiFile is KtFile) {
|
||||
if (!ProjectRootsUtil.isInProjectOrLibSource(psiFile)) return emptyList()
|
||||
return DebuggerClassNameProvider(myDebugProcess, scopes).getClassesForPosition(sourcePosition)
|
||||
return DebuggerClassNameProvider(myDebugProcess).getClassesForPosition(sourcePosition)
|
||||
}
|
||||
|
||||
if (psiFile is ClsFileImpl) {
|
||||
@@ -286,7 +303,7 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
||||
}
|
||||
|
||||
fun originalClassNamesForPosition(position: SourcePosition): List<String> {
|
||||
return DebuggerClassNameProvider(myDebugProcess, scopes, findInlineUseSites = false).getOuterClassNamesForPosition(position)
|
||||
return DebuggerClassNameProvider(myDebugProcess, findInlineUseSites = false).getOuterClassNamesForPosition(position)
|
||||
}
|
||||
|
||||
override fun locationsOfLine(type: ReferenceType, position: SourcePosition): List<Location> {
|
||||
@@ -325,7 +342,7 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
||||
throw NoDataException.INSTANCE
|
||||
}
|
||||
|
||||
val classNames = DebuggerClassNameProvider(myDebugProcess, scopes).getOuterClassNamesForPosition(position)
|
||||
val classNames = DebuggerClassNameProvider(myDebugProcess).getOuterClassNamesForPosition(position)
|
||||
return classNames.flatMap { name ->
|
||||
listOfNotNull(
|
||||
myDebugProcess.requestsManager.createClassPrepareRequest(requestor, name),
|
||||
|
||||
Reference in New Issue
Block a user