Java: clarify refactoring warning message (IDEA-359779)

GitOrigin-RevId: 8666270b887ebdce6c639a6deee40dd5273fff0d
This commit is contained in:
Bas Leijdekkers
2024-09-27 17:19:25 +02:00
committed by intellij-monorepo-bot
parent c0ca8d8600
commit 7eab69be22
5 changed files with 55 additions and 34 deletions

View File

@@ -225,7 +225,6 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(
() -> ReadAction.run(() -> {
PsiCodeBlock body = Objects.requireNonNull(myMethod.getBody());
if (!myInlineThisOnly) {
final PsiMethod[] superMethods = myMethod.findSuperMethods();
for (PsiMethod method : superMethods) {
@@ -252,7 +251,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
conflicts.putValue(element, JavaRefactoringBundle.message("inlined.method.will.be.transformed.to.single.return.form"));
}
final String errorMessage = checkUnableToInsertCodeBlock(body, element);
final String errorMessage = checkUnableToInsertCodeBlock(myMethod.getBody(), element);
if (errorMessage != null) {
conflicts.putValue(element, errorMessage);
}
@@ -265,7 +264,7 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
else if (myReference instanceof PsiMethodReferenceExpression) {
processSideEffectsInMethodReferenceQualifier(conflicts, (PsiMethodReferenceExpression)myReference);
}
addInaccessibleMemberConflicts(body, usagesIn, new ReferencedElementsCollector(), conflicts);
addInaccessibleMemberConflicts(myMethod, usagesIn, new ReferencedElementsCollector(), conflicts);
addInaccessibleSuperCallsConflicts(usagesIn, conflicts);
}),
RefactoringBundle.message("detecting.possible.conflicts"), true, myProject)) {
@@ -346,20 +345,21 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
});
}
public static void addInaccessibleMemberConflicts(PsiElement element,
public static void addInaccessibleMemberConflicts(PsiMethod method,
UsageInfo[] usages,
ReferencedElementsCollector collector,
MultiMap<PsiElement, @DialogMessage String> conflicts) {
element.accept(collector);
final Map<PsiMember, Set<PsiMember>> containersToReferenced = getInaccessible(collector.myReferencedMembers, usages, element);
containersToReferenced.forEach((container, referencedInaccessible) -> {
for (PsiMember referenced : referencedInaccessible) {
final String referencedDescription = RefactoringUIUtil.getDescription(referenced, true);
PsiCodeBlock body = Objects.requireNonNull(method.getBody());
body.accept(collector);
final Map<PsiMember, Set<PsiMember>> locationsToInaccessibles = getInaccessible(collector.myReferencedMembers, usages, method);
String methodDescription = RefactoringUIUtil.getDescription(method, true);
locationsToInaccessibles.forEach((container, inaccessibles) -> {
for (PsiMember inaccessible : inaccessibles) {
final String referencedDescription = RefactoringUIUtil.getDescription(inaccessible, true);
final String containerDescription = RefactoringUIUtil.getDescription(container, true);
String message = RefactoringBundle.message("0.that.is.used.in.inlined.method.is.not.accessible.from.call.site.s.in.1",
referencedDescription, containerDescription);
conflicts.putValue(container, StringUtil.capitalize(message));
String message = RefactoringBundle.message("0.which.is.used.in.1.not.accessible.from.call.site.s.in.2",
referencedDescription, methodDescription, containerDescription);
conflicts.putValue(usages.length == 1 ? inaccessible : container, StringUtil.capitalize(message));
}
});
}
@@ -424,13 +424,11 @@ public class InlineMethodProcessor extends BaseRefactoringProcessor {
}
}
@Nullable
@Override
protected String getRefactoringId() {
return "refactoring.inline.method";
}
@Nullable
@Override
protected RefactoringEventData getBeforeData() {
final RefactoringEventData data = new RefactoringEventData();

View File

@@ -1,10 +1,12 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.refactoring.inline;
import com.intellij.java.refactoring.JavaRefactoringBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -15,6 +17,7 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.BaseRefactoringProcessor;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.rename.NonCodeUsageInfoFactory;
import com.intellij.refactoring.util.RefactoringUIUtil;
import com.intellij.refactoring.util.TextOccurrencesUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
@@ -28,7 +31,6 @@ import java.util.*;
import static com.intellij.util.ObjectUtils.tryCast;
public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
private static final Logger LOG = Logger.getInstance(InlineToAnonymousClassProcessor.class);
@@ -48,7 +50,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
myClass = psiClass;
myCallToInline = callToInline;
myInlineThisOnly = inlineThisOnly;
if (myInlineThisOnly) assert myCallToInline != null;
assert !myInlineThisOnly || myCallToInline != null;
mySearchInComments = searchInComments;
mySearchInNonJavaFiles = searchInNonJavaFiles;
}
@@ -152,7 +154,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
super.checkAddMember(member);
}
};
InlineMethodProcessor.addInaccessibleMemberConflicts(myClass, usages, collector, result);
addInaccessibleMemberConflicts(usages, collector, result);
myClass.accept(new JavaRecursiveElementVisitor(){
@Override
public void visitParameter(@NotNull PsiParameter parameter) {
@@ -200,6 +202,29 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
return result;
}
private void addInaccessibleMemberConflicts(UsageInfo[] usages,
ReferencedElementsCollector collector,
MultiMap<PsiElement, @NlsContexts.DialogMessage String> conflicts) {
PsiElement element = myClass.getLBrace();
while (element != null) {
element.accept(collector);
element = element.getNextSibling();
}
final Map<PsiMember, Set<PsiMember>> containersToReferenced =
InlineMethodProcessor.getInaccessible(collector.myReferencedMembers, usages, myClass);
String classDescription = RefactoringUIUtil.getDescription(myClass, true);
containersToReferenced.forEach((container, inaccessibles) -> {
for (PsiMember inaccessible : inaccessibles) {
final String referencedDescription = RefactoringUIUtil.getDescription(inaccessible, true);
final String containerDescription = RefactoringUIUtil.getDescription(container, true);
String message = RefactoringBundle.message("0.which.is.used.in.1.not.accessible.from.call.site.s.in.2",
referencedDescription, classDescription, containerDescription);
conflicts.putValue(usages.length == 1 ? inaccessible : container, StringUtil.capitalize(message));
}
});
}
@Override
protected void performRefactoring(UsageInfo @NotNull [] usages) {
final PsiClassType superType = getSuperType(myClass);
@@ -310,12 +335,7 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
}
else {
PsiClassType[] classTypes = aClass.getExtendsListTypes();
if (classTypes.length > 0) {
superType = classTypes [0];
}
else {
superType = factory.createType(superClass);
}
superType = classTypes.length > 0 ? classTypes[0] : factory.createType(superClass);
}
return superType;
}
@@ -325,5 +345,4 @@ public class InlineToAnonymousClassProcessor extends BaseRefactoringProcessor {
protected String getCommandName() {
return JavaRefactoringBundle.message("inline.to.anonymous.command.name", myClass.getQualifiedName());
}
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.refactoring.inline;
import com.intellij.JavaTestUtil;
@@ -406,7 +406,9 @@ public class InlineMethodTest extends LightRefactoringTestCase {
}
public void testInaccessibleConstructorInInlinedMethod() {
doTestConflict("Constructor <b><code>SomeClass.SomeClass()</code></b> that is used in inlined method is not accessible from call site(s) in method <b><code>InlineWithPrivateConstructorAccessMain.main(String...)</code></b>");
doTestConflict("Constructor <b><code>SomeClass.SomeClass()</code></b> will not be accessible when method " +
"<b><code>SomeClass.createInstance()</code></b> is inlined into method " +
"<b><code>InlineWithPrivateConstructorAccessMain.main(String...)</code></b>");
}
public void testPreserveResultedVariableIfInitializerIsNotSideEffectsFree() {
@@ -434,7 +436,8 @@ public class InlineMethodTest extends LightRefactoringTestCase {
}
public void testInaccessibleFieldInSuperClass() {
doTestConflict("Field <b><code>A.i</code></b> that is used in inlined method is not accessible from call site(s) in method <b><code>B.bar()</code></b>");
doTestConflict("Field <b><code>A.i</code></b> will not be accessible when method <b><code>A.foo()</code></b> is inlined into " +
"method <b><code>B.bar()</code></b>");
}
public void testPrivateFieldInSuperClassInSameFile() {

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.refactoring.inline;
import com.intellij.JavaTestUtil;
@@ -18,7 +18,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
public class InlineToAnonymousClassTest extends LightRefactoringTestCase {
@NotNull
@Override
@@ -374,12 +373,13 @@ public class InlineToAnonymousClassTest extends LightRefactoringTestCase {
}
public void testNoInlineRecursiveAccess() {
doTestConflict("Class cannot be inlined because a call to its member inside body", "Class cannot be inlined because a call to its member inside body");
doTestConflict("Class cannot be inlined because a call to its member inside body",
"Class cannot be inlined because a call to its member inside body");
}
public void testConflictInaccessibleOuterField() {
doTestConflict(
"Field <b><code>C2.a</code></b> that is used in inlined method is not accessible from call site(s) in method <b><code>C2User.test()</code></b>");
doTestConflict("Field <b><code>C2.a</code></b> will not be accessible when class <b><code>C2.C2Inner</code></b> " +
"is inlined into method <b><code>C2User.test()</code></b>");
}
public void testGetClassConflict() {

View File

@@ -246,6 +246,7 @@ refactoring.is.not.supported.when.return.statement.interrupts.the.execution.flow
refactoring.is.not.supported.for.recursive.methods={0} refactoring may not be applied to remove recursive methods.\nYou can inline only individual method calls.
inline.method.command=Inlining Method {0}
0.that.is.used.in.inlined.method.is.not.accessible.from.call.site.s.in.1={0} that is used in inlined method is not accessible from call site(s) in {1}
0.which.is.used.in.1.not.accessible.from.call.site.s.in.2={0} will not be accessible when {1} is inlined into {2}
dialog.message.cannot.inline.reference.from.0=Cannot inline reference from {0}
dialog.message.method.overridden.in.language.that.doesn.t.support.this.refactoring={0} is overridden using {1}. This language doesn''t support the Introduce Parameter Object refactoring
0.already.contains.a.1={0} already contains a {1}