[java-highlighting] Provide fix for "The receiver name does not match the enclosing class type"

IDEA-273225

GitOrigin-RevId: aac09cbfcb60a1757c7b142ac888979148d4e7cc
This commit is contained in:
Andrey.Cherkasov
2022-02-08 05:20:31 +03:00
committed by intellij-monorepo-bot
parent 6766724651
commit 7ce1003bd9
12 changed files with 130 additions and 3 deletions

View File

@@ -1,4 +1,4 @@
// 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.
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.intention;
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar;
@@ -569,4 +569,20 @@ public abstract class QuickFixFactory {
* @return a new fix
*/
public abstract @NotNull IntentionAction createSetVariableTypeFix(@NotNull PsiVariable variable, @NotNull PsiType type);
/**
* Creates a fix that changes the name of the receiver parameter
*
* @param parameter receiver parameter to change name for
* @param newName new name of the receiver parameter
* <p>
* In an instance method the name of the receiver parameter must be <code>this</code>.
* <p>
* In an inner class's constructor the name of the receiver parameter must be <i>Identifier</i> . <code>this</code>
* where <i>Identifier</i> is the simple name of the class or interface which is the immediately enclosing type
* declaration of the inner class.
* @return a new fix
*/
public abstract @NotNull IntentionAction createReceiverParameterNameFix(@NotNull PsiReceiverParameter parameter,
@NotNull String newName);
}

View File

@@ -801,7 +801,8 @@ public final class AnnotationsHighlightUtil {
PsiMethod method = (PsiMethod)owner;
PsiClass enclosingClass = method.getContainingClass();
if (method.isConstructor() && enclosingClass != null) {
boolean isConstructor = method.isConstructor();
if (isConstructor && enclosingClass != null) {
enclosingClass = enclosingClass.getContainingClass();
}
@@ -818,7 +819,19 @@ public final class AnnotationsHighlightUtil {
PsiThisExpression identifier = parameter.getIdentifier();
if (!enclosingClass.equals(PsiUtil.resolveClassInType(identifier.getType()))) {
String text = JavaErrorBundle.message("receiver.name.mismatch");
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(identifier).descriptionAndTooltip(text).create();
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(identifier).descriptionAndTooltip(text).create();
String name;
if (isConstructor) {
String className = enclosingClass.getName();
name = className != null ? className + ".this" : null;
}
else {
name = "this";
}
if (name != null) {
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createReceiverParameterNameFix(parameter, name));
}
return info;
}
}

View File

@@ -195,6 +195,8 @@ fix.variable.type.family=Fix variable type
fix.variable.type.text=Change {0} ''{1}'' type to ''{2}''
fix.receiver.parameter.type.family=Fix receiver parameter type
fix.receiver.parameter.type.text=Change to the enclosing class type
fix.receiver.parameter.name.family=Fix the name of the receiver parameter
fix.receiver.parameter.name.text=Change to ''{0}''
# Sample: Boolean b = "true"; -> Boolean b = Boolean.valueOf("true");
wrap.expression.using.static.accessor.family=Wrap expression

View File

@@ -0,0 +1,44 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReceiverParameter;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ReceiverParameterNameFix extends LocalQuickFixAndIntentionActionOnPsiElement {
private final String myNewName;
public ReceiverParameterNameFix(@NotNull PsiReceiverParameter parameter, @NotNull String newName) {
super(parameter);
myNewName = newName;
}
@Override
@NotNull
public String getText() {
return QuickFixBundle.message("fix.receiver.parameter.name.text", myNewName);
}
@NotNull
@Override
public String getFamilyName() {
return QuickFixBundle.message("fix.receiver.parameter.name.family");
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
CommentTracker ct = new CommentTracker();
ct.replaceExpressionAndRestoreComments(((PsiReceiverParameter)startElement).getIdentifier(), myNewName);
}
}

View File

@@ -1145,4 +1145,9 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
public @NotNull IntentionAction createSetVariableTypeFix(@NotNull PsiVariable variable, @NotNull PsiType type) {
return new SetVariableTypeFix(variable, type);
}
@Override
public @NotNull IntentionAction createReceiverParameterNameFix(@NotNull PsiReceiverParameter parameter, @NotNull String newName) {
return new ReceiverParameterNameFix(parameter, newName);
}
}

View File

@@ -0,0 +1,6 @@
// "Change to 'A.this'" "true"
class A {
class B {
B(A A.this) {}
}
}

View File

@@ -0,0 +1,6 @@
// "Change to 'A.this'" "true"
class A {
class B {
B(A A.this) {}
}
}

View File

@@ -0,0 +1,6 @@
// "Change to 'this'" "true"
class A {
class B {
void m(B this) {}
}
}

View File

@@ -0,0 +1,6 @@
// "Change to 'A.this'" "true"
class A {
class B {
B(A this<caret>) {}
}
}

View File

@@ -0,0 +1,6 @@
// "Change to 'A.this'" "true"
class A {
class B {
B(A B.this<caret>) {}
}
}

View File

@@ -0,0 +1,6 @@
// "Change to 'this'" "true"
class A {
class B {
void m(B A.this<caret>) {}
}
}

View File

@@ -0,0 +1,11 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInsight.daemon.quickFix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
public class ReceiverParameterNameFixTest extends LightQuickFixParameterizedTestCase {
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/receiverParameterName";
}
}