Debugger: Do not assume we are inside the class body when in '}' (KT-15259)
This commit is contained in:
+48
-12
@@ -6,11 +6,12 @@
|
||||
package org.jetbrains.kotlin.idea.debugger
|
||||
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.idea.debugger.KotlinEditorTextProvider.Companion.isAcceptedAsCodeFragmentContext
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
|
||||
fun getContextElement(elementAt: PsiElement?): PsiElement? {
|
||||
@@ -25,17 +26,41 @@ fun getContextElement(elementAt: PsiElement?): PsiElement? {
|
||||
}
|
||||
|
||||
val containingFile = elementAt.containingFile
|
||||
if (containingFile is PsiJavaFile) return elementAt
|
||||
if (containingFile !is KtFile) return null
|
||||
|
||||
// elementAt can be PsiWhiteSpace when codeFragment is created from line start offset (in case of first opening EE window)
|
||||
val lineStartOffset = if (elementAt is PsiWhiteSpace || elementAt is PsiComment) {
|
||||
PsiTreeUtil.skipSiblingsForward(elementAt, PsiWhiteSpace::class.java, PsiComment::class.java)?.textOffset
|
||||
?: elementAt.textOffset
|
||||
} else {
|
||||
elementAt.textOffset
|
||||
if (containingFile is PsiJavaFile) {
|
||||
return elementAt
|
||||
}
|
||||
|
||||
if (containingFile !is KtFile) {
|
||||
return null
|
||||
}
|
||||
|
||||
val accurateElement = getAccurateContextElement(elementAt, containingFile)
|
||||
if (accurateElement != null) {
|
||||
return accurateElement
|
||||
}
|
||||
|
||||
return containingFile
|
||||
}
|
||||
|
||||
private fun getAccurateContextElement(elementAt: PsiElement, containingFile: KtFile): PsiElement? {
|
||||
// elementAt can be PsiWhiteSpace when codeFragment is created from line start offset (in case of first opening EE window)
|
||||
val elementAtSkippingWhitespaces = getElementSkippingWhitespaces(elementAt)
|
||||
|
||||
if (elementAtSkippingWhitespaces is LeafPsiElement && elementAtSkippingWhitespaces.elementType == KtTokens.RBRACE) {
|
||||
val classBody = elementAtSkippingWhitespaces.parent as? KtClassBody
|
||||
val classOrObject = classBody?.parent as? KtClassOrObject
|
||||
var declarationParent = classOrObject?.parent
|
||||
if (declarationParent is KtObjectLiteralExpression) {
|
||||
declarationParent = declarationParent.parent
|
||||
}
|
||||
|
||||
if (declarationParent != null) {
|
||||
return getAccurateContextElement(declarationParent, containingFile)
|
||||
}
|
||||
}
|
||||
|
||||
val lineStartOffset = elementAtSkippingWhitespaces.textOffset
|
||||
|
||||
val targetExpression = PsiTreeUtil.findElementOfClassAtOffset(containingFile, lineStartOffset, KtExpression::class.java, false)
|
||||
|
||||
if (targetExpression != null) {
|
||||
@@ -52,5 +77,16 @@ fun getContextElement(elementAt: PsiElement?): PsiElement? {
|
||||
?.let { return it }
|
||||
}
|
||||
|
||||
return containingFile
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getElementSkippingWhitespaces(elementAt: PsiElement): PsiElement {
|
||||
if (elementAt is PsiWhiteSpace || elementAt is PsiComment) {
|
||||
val newElement = PsiTreeUtil.skipSiblingsForward(elementAt, PsiWhiteSpace::class.java, PsiComment::class.java)
|
||||
if (newElement != null) {
|
||||
return newElement
|
||||
}
|
||||
}
|
||||
|
||||
return elementAt
|
||||
}
|
||||
Reference in New Issue
Block a user