mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
rename records components (IDEA-228462)
GitOrigin-RevId: f673a1841f9f8ca454a73b9f2a38b3e7edacbf65
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c936621849
commit
90d15bfaf0
@@ -5,6 +5,8 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightRecordCanonicalConstructor;
|
||||
import com.intellij.psi.impl.light.LightRecordMember;
|
||||
import com.intellij.psi.javadoc.PsiDocTag;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
@@ -148,6 +150,14 @@ public class JavaTargetElementEvaluator extends TargetElementEvaluatorEx2 implem
|
||||
return JavaPsiFacade.getInstance(refElement.getProject()).findClass(qualifiedName, refElement.getResolveScope());
|
||||
}
|
||||
}
|
||||
|
||||
if (refElement instanceof LightRecordMember) {
|
||||
return ((LightRecordMember)refElement).getRecordComponent();
|
||||
}
|
||||
|
||||
if (refElement instanceof LightRecordCanonicalConstructor) {
|
||||
return ((LightRecordCanonicalConstructor)refElement).getContainingClass();
|
||||
}
|
||||
}
|
||||
return super.adjustReferenceOrReferencedElement(file, editor, offset, flags, refElement);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightRecordMethod;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
@@ -137,6 +138,7 @@ public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
|
||||
|
||||
if (elem instanceof PsiMethod) {
|
||||
PsiMethod actualMethod = (PsiMethod) elem;
|
||||
if (actualMethod instanceof LightRecordMethod) return;
|
||||
if (!methodAndOverriders.contains(actualMethod)) {
|
||||
PsiClass outerClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
while (outerClass != null) {
|
||||
@@ -327,6 +329,10 @@ public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
PsiRecordComponent recordComponent = JavaPsiRecordUtil.getRecordComponentForAccessor(psiMethod);
|
||||
if (recordComponent != null) {
|
||||
return recordComponent;
|
||||
}
|
||||
return SuperMethodWarningUtil.checkSuperMethod(psiMethod, RefactoringBundle.message("to.rename"));
|
||||
}
|
||||
|
||||
@@ -345,6 +351,11 @@ public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
|
||||
super.substituteElementToRename(element, editor, renameCallback);
|
||||
}
|
||||
else {
|
||||
PsiRecordComponent recordComponent = JavaPsiRecordUtil.getRecordComponentForAccessor(psiMethod);
|
||||
if (recordComponent != null) {
|
||||
renameCallback.pass(recordComponent);
|
||||
return;
|
||||
}
|
||||
SuperMethodWarningUtil.checkSuperMethod(psiMethod, "Rename", new PsiElementProcessor<PsiMethod>() {
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiMethod method) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.refactoring.util.RefactoringMessageUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -129,6 +130,17 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
|
||||
if (element instanceof PsiField && JavaLanguage.INSTANCE.equals(element.getLanguage())) {
|
||||
prepareFieldRenaming((PsiField)element, newName, allRenames);
|
||||
}
|
||||
if (element instanceof PsiRecordComponent) {
|
||||
PsiClass containingClass = ((PsiRecordComponent)element).getContainingClass();
|
||||
if (containingClass != null) {
|
||||
PsiMethod explicitGetter = ContainerUtil
|
||||
.find(containingClass.findMethodsByName(((PsiRecordComponent)element).getName(), false), m -> m.getParameters().length == 0);
|
||||
|
||||
if (explicitGetter != null) {
|
||||
addOverriddenAndImplemented(explicitGetter, newName, null, newName, JavaCodeStyleManager.getInstance(element.getProject()), allRenames);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void prepareFieldRenaming(PsiField field, String newName, final Map<PsiElement, String> allRenames) {
|
||||
|
||||
+23
-2
@@ -7,8 +7,11 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchRequestCollector;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.JavaPsiRecordUtil;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class JavaRecordComponentSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {
|
||||
@Override
|
||||
@@ -23,10 +26,19 @@ public class JavaRecordComponentSearcher extends QueryExecutorBase<PsiReference,
|
||||
queryParameters.getEffectiveSearchScope(),
|
||||
false,
|
||||
info.myLightMethod);
|
||||
|
||||
optimizer.searchWord(info.myName,
|
||||
new LocalSearchScope(info.myClass),
|
||||
true,
|
||||
info.myLightField);
|
||||
|
||||
PsiParameter parameter = info.myLightCompactConstructorParameter;
|
||||
if (parameter != null) {
|
||||
optimizer.searchWord(info.myName,
|
||||
new LocalSearchScope(parameter.getDeclarationScope()),
|
||||
true,
|
||||
parameter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,27 +49,36 @@ public class JavaRecordComponentSearcher extends QueryExecutorBase<PsiReference,
|
||||
if (name == null) return null;
|
||||
PsiClass containingClass = recordComponent.getContainingClass();
|
||||
if (containingClass == null) return null;
|
||||
|
||||
PsiMethod[] methods = containingClass.findMethodsByName(name, false);
|
||||
if (methods.length != 1) return null;
|
||||
|
||||
PsiField field = containingClass.findFieldByName(name, false);
|
||||
if (field == null) return null;
|
||||
PsiMethod method = methods[0];
|
||||
return new RecordNavigationInfo(method, field, name, recordComponent.getContainingClass());
|
||||
|
||||
PsiMethod compactConstructor = ContainerUtil.find(containingClass.getConstructors(), JavaPsiRecordUtil::isCompactConstructor);
|
||||
PsiParameter parameter = compactConstructor != null
|
||||
? ContainerUtil.find(compactConstructor.getParameterList().getParameters(), p -> name.equals(p.getName()))
|
||||
: null;
|
||||
return new RecordNavigationInfo(methods[0], field, parameter, name, recordComponent.getContainingClass());
|
||||
});
|
||||
}
|
||||
|
||||
private static class RecordNavigationInfo {
|
||||
@NotNull final PsiMethod myLightMethod;
|
||||
@NotNull final PsiField myLightField;
|
||||
@Nullable final PsiParameter myLightCompactConstructorParameter;
|
||||
@NotNull final String myName;
|
||||
@NotNull final PsiClass myClass;
|
||||
|
||||
private RecordNavigationInfo(@NotNull PsiMethod lightMethod,
|
||||
@NotNull PsiField lightField,
|
||||
@Nullable PsiParameter parameter,
|
||||
@NotNull String name,
|
||||
@NotNull PsiClass aClass) {
|
||||
myLightMethod = lightMethod;
|
||||
myLightField = lightField;
|
||||
myLightCompactConstructorParameter = parameter;
|
||||
myName = name;
|
||||
myClass = aClass;
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
interface IBar {
|
||||
int bar();
|
||||
}
|
||||
record Foo(int bar) implements IBar{
|
||||
public Foo { this.bar = b<caret>ar; }
|
||||
public int bar() { return bar; }
|
||||
public int test() { return bar(); }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
interface IBar {
|
||||
int baz();
|
||||
}
|
||||
record Foo(int baz) implements IBar{
|
||||
public Foo { this.baz = b<caret>az; }
|
||||
public int baz() { return baz; }
|
||||
public int test() { return baz(); }
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
record Foo(int bar) {
|
||||
public Foo { this.bar = bar; }
|
||||
public int b<caret>ar() { return bar; }
|
||||
public int test() { return bar(); }
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
record Foo(int baz) {
|
||||
public Foo { this.baz = baz; }
|
||||
public int b<caret>az() { return baz; }
|
||||
public int test() { return baz(); }
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
record Foo(int b<caret>ar) {
|
||||
public Foo { this.bar = bar; }
|
||||
public int test() { return bar(); }
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
record Foo(int b<caret>az) {
|
||||
public Foo { this.baz = baz; }
|
||||
public int test() { return baz(); }
|
||||
}
|
||||
+18
@@ -34,6 +34,24 @@ public class LightRecordsHighlightingTest extends LightJavaCodeInsightFixtureTes
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testRenameOnRecordComponent() {
|
||||
doTestRename();
|
||||
}
|
||||
|
||||
public void testRenameOnCompactConstructorReference() {
|
||||
doTestRename();
|
||||
}
|
||||
|
||||
public void testRenameOnExplicitGetter() {
|
||||
doTestRename();
|
||||
}
|
||||
|
||||
private void doTestRename() {
|
||||
doTest();
|
||||
myFixture.renameElementAtCaret("baz");
|
||||
myFixture.checkResultByFile(getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
myFixture.addClass("package java.lang; public abstract class Record {" +
|
||||
"public abstract boolean equals(Object obj);" +
|
||||
|
||||
Reference in New Issue
Block a user