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
|
||||
}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
val global = 2
|
||||
|
||||
fun makeFace() = object : ObjectFace {
|
||||
val inObject = 1
|
||||
<caret>}
|
||||
<caret>val inObject = 1
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package kt15259
|
||||
|
||||
interface ObjectFace
|
||||
|
||||
private fun makeFace() = object : ObjectFace {
|
||||
//Breakpoint!
|
||||
}
|
||||
|
||||
fun main() {
|
||||
makeFace()
|
||||
}
|
||||
|
||||
// EXPRESSION: this
|
||||
// RESULT: 'this' is not defined in this context
|
||||
@@ -0,0 +1,7 @@
|
||||
LineBreakpoint created at kt15259.kt:7
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
kt15259.kt:7
|
||||
Disconnected from the target VM
|
||||
|
||||
Process finished with exit code 0
|
||||
Generated
+5
@@ -256,6 +256,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt12206BasePropertyWithoutBackingField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt15259.kt")
|
||||
public void testKt15259() throws Exception {
|
||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt15259.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt17514.kt")
|
||||
public void testKt17514() throws Exception {
|
||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/kt17514.kt");
|
||||
|
||||
Reference in New Issue
Block a user