From 8329aab5c4182c73e27e64de7925d250ad0fa18b Mon Sep 17 00:00:00 2001 From: "Alexey.Merkulov" Date: Mon, 27 Jul 2026 14:57:21 +0200 Subject: [PATCH] [debugger] IJPL-251143 Do not instrument breakpoints with changing local variables IJ-CR-215549 (cherry picked from commit 18f61afb2c6ad3dae45ac5d1c012ac26e5fdec1c) (cherry picked from commit 22b67d10a47645524bfea06e72facad70250715a) IJ-CR-216735 GitOrigin-RevId: cdb9179c16ccedd86c4a80a2e55c3e0111091973 --- .../ExtractLightMethodObjectHandler.java | 20 ++++++++++++++++++- .../LightMethodObjectExtractedData.java | 15 +++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java index bebfb9c760f7..040716fb8b66 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java @@ -269,8 +269,17 @@ public final class ExtractLightMethodObjectHandler { extractMethodObjectProcessor.getExtractProcessor().setShowErrorDialogs(false); final ExtractMethodObjectProcessor.MyExtractMethodProcessor extractProcessor = extractMethodObjectProcessor.getExtractProcessor(); + boolean hasOutputVariables = false; int startOffsetInContainer; if (extractProcessor.prepare()) { + // For value-producing fragments, this includes at least the synthetic result variable. Ignore variables declared inside + // the fragment; only variables declared outside need to be written back to the original frame. + for (PsiVariable outputVariable : extractProcessor.getOutputVariables()) { + if (!isDeclaredInside(outputVariable, elementsCopy)) { + hasOutputVariables = true; + break; + } + } boolean shown = extractProcessor.showDialog(); if (!shown) { throw new IllegalStateException("Must return success"); @@ -324,7 +333,7 @@ public final class ExtractLightMethodObjectHandler { final String generatedCall = copy.getText().substring(startOffset, outStatement.getTextOffset()).trim(); return new LightMethodObjectExtractedData(generatedCall, (PsiClass)CodeStyleManager.getInstance(project).reformat(generatedClass), - originalAnchor, useMagicAccessor); + originalAnchor, useMagicAccessor, hasOutputVariables); } private static void generateResult(@NotNull Project project, @@ -344,6 +353,15 @@ public final class ExtractLightMethodObjectHandler { } } + private static boolean isDeclaredInside(@NotNull PsiVariable variable, PsiElement[] elements) { + for (PsiElement element : elements) { + if (PsiTreeUtil.isAncestor(element, variable, false)) { + return true; + } + } + return false; + } + private static @Nullable PsiMethodCallExpression findCallExpression(@NotNull PsiFile copy, @NotNull PsiMethod method) { PsiMethodCallExpression[] result = new PsiMethodCallExpression[1]; copy.accept(new JavaRecursiveElementVisitor() { diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/LightMethodObjectExtractedData.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/LightMethodObjectExtractedData.java index 39912f4cb84e..0083fa778ba1 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/LightMethodObjectExtractedData.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/LightMethodObjectExtractedData.java @@ -6,6 +6,7 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiType; +import org.jetbrains.annotations.ApiStatus; public class LightMethodObjectExtractedData { public static final Key REFERENCE_METHOD = Key.create("CompilingEvaluatorReferenceMethod"); @@ -14,12 +15,19 @@ public class LightMethodObjectExtractedData { private final PsiClass myGeneratedInnerClass; private final PsiElement myAnchor; private final boolean myUseMagicAccessor; + private final boolean myHasOutputVariables; - public LightMethodObjectExtractedData(String generatedCallText, PsiClass generatedInnerClass, PsiElement anchor, boolean useMagicAccessor) { + @ApiStatus.Internal + public LightMethodObjectExtractedData(String generatedCallText, + PsiClass generatedInnerClass, + PsiElement anchor, + boolean useMagicAccessor, + boolean hasOutputVariables) { myGeneratedCallText = generatedCallText; myGeneratedInnerClass = generatedInnerClass; myAnchor = anchor; myUseMagicAccessor = useMagicAccessor; + myHasOutputVariables = hasOutputVariables; } public PsiElement getAnchor() { @@ -37,4 +45,9 @@ public class LightMethodObjectExtractedData { public boolean useMagicAccessor() { return myUseMagicAccessor; } + + @ApiStatus.Internal + public boolean hasOutputVariables() { + return myHasOutputVariables; + } }