Debugger: get topmost element at offset as contextElement
This commit is contained in:
+7
-2
@@ -70,8 +70,13 @@ public class CodeFragmentAnalyzer(
|
||||
is JetDeclarationWithBody -> this.getBodyExpression()
|
||||
is JetBlockExpression -> this.getStatements().lastOrNull()
|
||||
else -> {
|
||||
this.siblings(forward = false, withItself = false).firstIsInstanceOrNull<JetExpression>()
|
||||
?: this.parents.firstIsInstanceOrNull<JetExpression>()
|
||||
val previousSibling = this.siblings(forward = false, withItself = false).firstIsInstanceOrNull<JetExpression>()
|
||||
if (previousSibling != null) return previousSibling
|
||||
for (parent in this.parents) {
|
||||
if (parent is JetWhenEntry || parent is JetIfExpression || parent is JetBlockExpression) return this
|
||||
if (parent is JetExpression) return parent
|
||||
}
|
||||
null
|
||||
}
|
||||
} ?: this
|
||||
}
|
||||
|
||||
@@ -284,4 +284,25 @@ public class CodeInsightUtils {
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <T> T getTopmostElementAtOffset(@NotNull PsiElement element, int offset, @NotNull Class<T> klass) {
|
||||
T lastElementOfType = null;
|
||||
if (klass.isInstance(element)) {
|
||||
lastElementOfType = (T) element;
|
||||
}
|
||||
do {
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent == null || (parent.getTextOffset() < offset) || parent instanceof JetBlockExpression) {
|
||||
break;
|
||||
}
|
||||
if (klass.isInstance(parent)) {
|
||||
lastElementOfType = (T) parent;
|
||||
}
|
||||
element = parent;
|
||||
}
|
||||
while(true);
|
||||
|
||||
return lastElementOfType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,14 +37,17 @@ import com.sun.jdi.PrimitiveValue
|
||||
import com.sun.jdi.Value
|
||||
import org.jetbrains.kotlin.asJava.KotlinLightClass
|
||||
import org.jetbrains.kotlin.idea.JetFileType
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.j2kText
|
||||
import org.jetbrains.kotlin.idea.debugger.KotlinEditorTextProvider
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
import java.util.HashMap
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import kotlin.reflect.jvm.java
|
||||
|
||||
class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
||||
private val LOG = Logger.getInstance(this.javaClass)
|
||||
@@ -143,14 +146,21 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
||||
val containingFile = elementAt.containingFile
|
||||
if (containingFile !is JetFile) return null
|
||||
|
||||
val expressionAtOffset = PsiTreeUtil.findElementOfClassAtOffset(containingFile, elementAt.textOffset, javaClass<JetExpression>(), false)
|
||||
if (expressionAtOffset != null && KotlinEditorTextProvider.isAcceptedAsCodeFragmentContext(elementAt)) {
|
||||
return expressionAtOffset
|
||||
var result = PsiTreeUtil.findElementOfClassAtOffset(containingFile, elementAt.textOffset, javaClass<JetExpression>(), false)
|
||||
if (result.check()) {
|
||||
return CodeInsightUtils.getTopmostElementAtOffset(result!!, result.textOffset, JetExpression::class.java)
|
||||
}
|
||||
|
||||
return KotlinEditorTextProvider.findExpressionInner(elementAt, true) ?: containingFile
|
||||
result = KotlinEditorTextProvider.findExpressionInner(elementAt, true)
|
||||
if (result.check()) {
|
||||
return result
|
||||
}
|
||||
|
||||
return containingFile
|
||||
}
|
||||
|
||||
private fun JetElement?.check(): Boolean = this != null && this.check { KotlinEditorTextProvider.isAcceptedAsCodeFragmentContext(it) } != null
|
||||
|
||||
//internal for tests
|
||||
fun createCodeFragmentForLabeledObjects(project: Project, markupMap: Map<*, ValueMarkup>): Pair<String, Map<String, Value>> {
|
||||
val sb = StringBuilder()
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
fun foo() {
|
||||
val a: Int? = 1
|
||||
if (a != null) {
|
||||
<caret> a
|
||||
<caret>a
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user