IDEA-323195 - introduced evaluation context key to control evaluation with helper

GitOrigin-RevId: 330d30283a01f502f31637abd5cccaec9976c9c5
This commit is contained in:
Egor Ushakov
2025-03-24 20:54:31 +00:00
committed by intellij-monorepo-bot
parent f9c56903a5
commit f034060eed
6 changed files with 23 additions and 9 deletions
@@ -178,6 +178,10 @@
<feedback.idleFeedbackSurvey implementation="com.intellij.debugger.feedback.KotlinDebuggerFeedbackSurvey"/>
<debugger.steppingListener implementation="com.intellij.debugger.engine.CancelingSteppingListener"/>
<registryKey defaultValue="[off*|auto|always]"
key="debugger.evaluate.method.helper"
description="Use helper to invoke methods avoiding the immediate return value collection"/>
</extensions>
<actions>
@@ -14,6 +14,7 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Attachment
import com.intellij.openapi.diagnostic.RuntimeExceptionWithAttachments
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.CommonClassNames
import com.intellij.rt.debugger.MethodInvoker
@@ -25,6 +26,9 @@ import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
object MethodInvokeUtils {
@JvmStatic
internal val INVOKE_WITH_HELPER_KEY: Key<Boolean> = Key<Boolean>("invoke.with.helper")
fun getHelperExceptionStackTrace(evaluationContext: EvaluationContextImpl, e: Exception): String? {
if (e !is EvaluateException) return null
val exceptionFromTargetVM = e.exceptionFromTargetVM ?: return null
@@ -83,8 +87,10 @@ internal fun tryInvokeWithHelper(
invocationOptions: Int,
internalEvaluate: Boolean,
): InvocationResult {
val useHelper = Registry.get("debugger.evaluate.method.helper").selectedOption
if (internalEvaluate ||
!Registry.`is`("debugger.evaluate.method.helper") ||
("auto" == useHelper && evaluationContext.getUserData(MethodInvokeUtils.INVOKE_WITH_HELPER_KEY) != true) ||
"off" == useHelper ||
isSet(invocationOptions, INVOKE_NONVIRTUAL) || //TODO: support
isPrimitiveType(method.returnTypeName()) ||
(isVoid(method) && !method.isConstructor) ||
@@ -1450,7 +1450,6 @@ public final class EvaluatorBuilderImpl implements EvaluatorBuilder {
PsiElement qualifier = expression.getQualifier();
PsiType interfaceType = expression.getFunctionalInterfaceType();
if (!Registry.is("debugger.compiling.evaluator.method.refs") &&
!Registry.is("debugger.evaluate.method.helper") &&
interfaceType != null &&
qualifier != null) {
String code = null;
@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.testFramework;
import com.intellij.codeInsight.CodeInsightSettings;
@@ -17,6 +17,7 @@ import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.registry.RegistryValue;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.util.text.Strings;
import com.intellij.openapi.vfs.LocalFileSystem;
@@ -1239,8 +1240,14 @@ Most likely there was an uncaught exception in asynchronous execution that resul
}
protected void setRegistryPropertyForTest(@NotNull String property, @SuppressWarnings("SameParameterValue") @NotNull String value) {
Registry.get(property).setValue(value);
Disposer.register(getTestRootDisposable(), () -> Registry.get(property).resetToDefault());
RegistryValue registryValue = Registry.get(property);
if (registryValue.isMultiValue()) {
registryValue.setSelectedOption(value);
}
else {
registryValue.setValue(value);
}
Disposer.register(getTestRootDisposable(), () -> registryValue.resetToDefault());
}
protected void allowAccessToDirsIfExists(@NotNull String @NotNull ... dirNames) {
@@ -660,8 +660,6 @@ debugger.attach.to.process.action=false
debugger.sa.jdwp.debug=false
debugger.add.rt.jar=true
debugger.add.rt.jar.description=Add rt.jar to the classpath
debugger.evaluate.method.helper=false
debugger.evaluate.method.helper.description=Use helper to invoke methods avoiding the immediate return value collection
debugger.evaluate.single.threaded.timeout=1000
debugger.evaluate.single.threaded.timeout.description=Number of milliseconds to evaluate resuming only the current thread, then resume all threads
debugger.evaluate.load.helper.in.separate.classloader=false
@@ -27,13 +27,13 @@ import static org.junit.Assume.assumeTrue;
public class EvaluationFailedTest extends FailEvaluationTestCase {
@Test
public void testEvaluationExceptionDetected() {
assumeFalse(Registry.is("debugger.evaluate.method.helper"));
assumeTrue("off".equals(Registry.get("debugger.evaluate.method.helper").getSelectedOption()));
doTest(true, "EvaluationExceptionDetected");
}
@Test
public void testEvaluationExceptionDetectedHelper() {
assumeTrue(Registry.is("debugger.evaluate.method.helper"));
assumeTrue("always".equals(Registry.get("debugger.evaluate.method.helper").getSelectedOption()));
doTest(true, "EvaluationExceptionDetected");
}