diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java index b922f9096371..4087787ce0ed 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java @@ -172,6 +172,23 @@ public class InlineLocalHandler extends JavaInlineActionHandler { final String localName = local.getName(); + final List innerClassesWithUsages = new ArrayList<>(); + final List innerClassUsages = new ArrayList<>(); + final PsiElement containingClass = PsiTreeUtil.getParentOfType(local, PsiClass.class, PsiLambdaExpression.class); + for (PsiElement element : allRefs) { + PsiElement innerClass = element; + while (innerClass != null) { + final PsiElement parentPsiClass = PsiTreeUtil.getParentOfType(innerClass.getParent(), PsiClass.class, PsiLambdaExpression.class); + if (parentPsiClass == containingClass) { + if (innerClass != element) { + innerClassesWithUsages.add(innerClass); + innerClassUsages.add(element); + } + break; + } + innerClass = parentPsiClass; + } + } final PsiCodeBlock containerBlock = PsiTreeUtil.getParentOfType(local, PsiCodeBlock.class); if (containerBlock == null) { final String message = RefactoringBundle.getCannotRefactorMessage( @@ -179,16 +196,10 @@ public class InlineLocalHandler extends JavaInlineActionHandler { CommonRefactoringUtil.showErrorHint(project, editor, message, getRefactoringName(local), HelpID.INLINE_VARIABLE); return null; } - - final List innerClassUsages = Collections.synchronizedList(new ArrayList<>()); - final PsiElement containingClass = PsiTreeUtil.getParentOfType(local, PsiClass.class, PsiLambdaExpression.class); - + final PsiExpression defToInline; try { - PsiElement refToInline = getRefToInline(local, allRefs, innerClassUsages, containingClass); - defToInline = getDefToInline(local, - refToInline != null ? refToInline : refExpr, - containerBlock, true); + defToInline = getDefToInline(local, innerClassesWithUsages.isEmpty() ? refExpr : innerClassesWithUsages.get(0), containerBlock, true); if (defToInline == null) { final String key = refExpr == null ? "variable.has.no.initializer" : "variable.has.no.dominating.definition"; String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message(key, localName)); @@ -349,33 +360,6 @@ public class InlineLocalHandler extends JavaInlineActionHandler { }; } - @Nullable - static PsiElement getRefToInline(@NotNull PsiLocalVariable local, - @NotNull Collection allRefs, - List innerClassUsages, - PsiElement containingClass) { - final List innerClassesWithUsages = Collections.synchronizedList(new ArrayList<>()); - for (PsiElement element : allRefs) { - PsiElement innerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, PsiLambdaExpression.class); - while (innerClass != containingClass && innerClass != null) { - final PsiElement parentPsiClass = PsiTreeUtil.getParentOfType(innerClass.getParent(), PsiClass.class, PsiLambdaExpression.class); - if (parentPsiClass == containingClass) { - if (innerClass instanceof PsiLambdaExpression) { - if (PsiTreeUtil.isAncestor(innerClass, local, false)) { - innerClassesWithUsages.add(element); - innerClass = parentPsiClass; - continue; - } - } - innerClassesWithUsages.add(innerClass); - innerClassUsages.add(element); - } - innerClass = parentPsiClass; - } - } - return innerClassesWithUsages.isEmpty() ? null : innerClassesWithUsages.get(0); - } - @NotNull static List> inlineOccurrences(@NotNull Project project, @NotNull PsiVariable local, diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java index db9ccc8277f0..5f325dac302b 100644 --- a/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineParameterExpressionProcessor.java @@ -26,7 +26,6 @@ import com.intellij.usageView.UsageInfo; import com.intellij.usageView.UsageViewDescriptor; import com.intellij.usageView.UsageViewUtil; import com.intellij.util.JavaPsiConstructorUtil; -import com.intellij.util.ObjectUtils; import com.intellij.util.VisibilityUtil; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; @@ -108,12 +107,7 @@ public class InlineParameterExpressionProcessor extends BaseRefactoringProcessor final PsiElement element = expression.resolve(); if (element instanceof PsiLocalVariable) { final PsiLocalVariable localVariable = (PsiLocalVariable)element; - final List innerClassUsages = Collections.synchronizedList(new ArrayList<>()); - final PsiElement containingClass = PsiTreeUtil.getParentOfType(localVariable, PsiClass.class, PsiLambdaExpression.class); - PsiElement refToInline = InlineLocalHandler.getRefToInline(localVariable, - Collections.singletonList(expression), - innerClassUsages, containingClass); - final PsiElement[] elements = DefUseUtil.getDefs(myCallingBlock, localVariable, ObjectUtils.notNull(refToInline, expression)); + final PsiElement[] elements = DefUseUtil.getDefs(myCallingBlock, localVariable, expression); if (elements.length == 1) { PsiExpression localInitializer = null; if (elements[0] instanceof PsiLocalVariable) { diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java index e48d5e70d905..d49bafc9dbe5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java @@ -1,4 +1,4 @@ -// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.psi.controlFlow; import com.intellij.openapi.diagnostic.Logger; @@ -257,6 +257,15 @@ public final class DefUseUtil { } public static PsiElement @NotNull [] getDefs(@NotNull PsiCodeBlock body, @NotNull PsiVariable def, @NotNull PsiElement ref, boolean rethrow) { + if (def instanceof PsiLocalVariable && ref instanceof PsiReferenceExpression && ((PsiReferenceExpression)ref).resolve() == def) { + final PsiElement containingClass = PsiTreeUtil.getParentOfType(def, PsiClass.class, PsiLambdaExpression.class); + PsiElement refContainer = PsiTreeUtil.getParentOfType(ref, PsiClass.class, PsiLambdaExpression.class); + while (containingClass != refContainer && refContainer != null) { + ref = refContainer; + refContainer = PsiTreeUtil.getParentOfType(refContainer.getParent(), PsiClass.class, PsiLambdaExpression.class); + } + } + try { RefsDefs refsDefs = new RefsDefs(body) { final PsiManager psiManager = def.getManager(); diff --git a/java/java-tests/testData/codeInsight/slice/backward/FinalVarAssignedBeforePassingToAnonymous.java b/java/java-tests/testData/codeInsight/slice/backward/FinalVarAssignedBeforePassingToAnonymous.java index 7eccbb108081..29cb80d256cc 100644 --- a/java/java-tests/testData/codeInsight/slice/backward/FinalVarAssignedBeforePassingToAnonymous.java +++ b/java/java-tests/testData/codeInsight/slice/backward/FinalVarAssignedBeforePassingToAnonymous.java @@ -3,8 +3,8 @@ class Foo { } void bar() { - final String res; - res = "a"; + final String res; + res = "a"; SwingUtilities.invokeLater(new Runnable() { @Override public void run() {