Debugger: allow Evaluate Expression in context of File (for some synthetic methods or when file was changed during debug and breakpoint line no longer match the actual line)
This commit is contained in:
@@ -78,6 +78,10 @@ public fun JetCodeFragment.getScopeAndDataFlowForAnalyzeFragment(
|
||||
scopeForContextElement = contextForElement[BindingContext.RESOLUTION_SCOPE, correctedContext]
|
||||
dataFlowInfo = contextForElement.getDataFlowInfo(correctedContext)
|
||||
}
|
||||
is JetFile -> {
|
||||
scopeForContextElement = resolveSession.getFileScopeProvider().getFileScope(context)
|
||||
dataFlowInfo = DataFlowInfo.EMPTY
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
|
||||
|
||||
@@ -56,9 +56,7 @@ class KotlinEditorTextProvider : EditorTextProvider {
|
||||
}
|
||||
|
||||
fun findExpressionInner(element: PsiElement, allowMethodCalls: Boolean): JetExpression? {
|
||||
if (PsiTreeUtil.getParentOfType(element, javaClass<JetUserType>(), javaClass<JetImportDirective>(), javaClass<JetPackageDirective>()) != null) {
|
||||
return null
|
||||
}
|
||||
if (!isAcceptedAsCodeFragmentContext(element)) return null
|
||||
|
||||
val jetElement = PsiTreeUtil.getParentOfType(element, javaClass<JetElement>())
|
||||
if (jetElement == null) return null
|
||||
@@ -116,6 +114,14 @@ class KotlinEditorTextProvider : EditorTextProvider {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private val NOT_ACCEPTED_AS_CONTEXT_TYPES =
|
||||
arrayOf(javaClass<JetUserType>(), javaClass<JetImportDirective>(), javaClass<JetPackageDirective>())
|
||||
|
||||
fun isAcceptedAsCodeFragmentContext(element: PsiElement): Boolean {
|
||||
return element.javaClass !in NOT_ACCEPTED_AS_CONTEXT_TYPES &&
|
||||
PsiTreeUtil.getParentOfType(element, *NOT_ACCEPTED_AS_CONTEXT_TYPES) == null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,10 +131,11 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
||||
}
|
||||
|
||||
val expressionAtOffset = PsiTreeUtil.findElementOfClassAtOffset(elementAt.getContainingFile()!!, elementAt.getTextOffset(), javaClass<JetExpression>(), false)
|
||||
if (expressionAtOffset != null) {
|
||||
if (expressionAtOffset != null && KotlinEditorTextProvider.isAcceptedAsCodeFragmentContext(elementAt)) {
|
||||
return expressionAtOffset
|
||||
}
|
||||
return KotlinEditorTextProvider.findExpressionInner(elementAt, true)
|
||||
|
||||
return KotlinEditorTextProvider.findExpressionInner(elementAt, true) ?: elementAt.getContainingFile()
|
||||
}
|
||||
|
||||
//internal for tests
|
||||
|
||||
+7
-6
@@ -77,11 +77,6 @@ fun getFunctionForExtractedFragment(
|
||||
val contextElement = getExpressionToAddDebugExpressionBefore(tmpFile, codeFragment.getContext(), breakpointLine)
|
||||
if (contextElement == null) return null
|
||||
|
||||
// Don't evaluate smth when breakpoint is on package directive (ex. for package classes)
|
||||
if (contextElement is JetFile) {
|
||||
throw EvaluateExceptionUtil.createEvaluateException("Cannot perform an action at this breakpoint ${breakpointFile.getName()}:${breakpointLine}")
|
||||
}
|
||||
|
||||
addImportsToFile(codeFragment.importsAsImportList(), tmpFile)
|
||||
|
||||
val newDebugExpressions = addDebugExpressionBeforeContextElement(codeFragment, contextElement)
|
||||
@@ -158,7 +153,7 @@ private fun getExpressionToAddDebugExpressionBefore(tmpFile: JetFile, contextEle
|
||||
return getExpressionToAddDebugExpressionBefore(tmpFile, containingFile.getContext(), line)
|
||||
}
|
||||
|
||||
fun shouldStop(el: PsiElement?, p: PsiElement?) = p is JetBlockExpression || el is JetDeclaration
|
||||
fun shouldStop(el: PsiElement?, p: PsiElement?) = p is JetBlockExpression || el is JetDeclaration || el is JetFile
|
||||
|
||||
var elementAt = tmpFile.getElementInCopy(contextElement)
|
||||
|
||||
@@ -192,6 +187,12 @@ private fun addDebugExpressionBeforeContextElement(codeFragment: JetCodeFragment
|
||||
}
|
||||
|
||||
val elementBefore = when {
|
||||
contextElement is JetFile -> {
|
||||
val fakeFunction = psiFactory.createFunction("fun _debug_fun_() {}")
|
||||
contextElement.add(psiFactory.createNewLine())
|
||||
val newFakeFun = contextElement.add(fakeFunction) as JetNamedFunction
|
||||
newFakeFun.getBodyExpression()!!.getLastChild()
|
||||
}
|
||||
contextElement is JetProperty && !contextElement.isLocal() -> {
|
||||
val delegateExpressionOrInitializer = contextElement.getDelegateExpressionOrInitializer()
|
||||
if (delegateExpressionOrInitializer != null) {
|
||||
|
||||
Reference in New Issue
Block a user