From 3d2c425834fa0cdbff8a918ff270cae8904fb9e7 Mon Sep 17 00:00:00 2001 From: Andrey Cherkasov Date: Tue, 25 Oct 2022 11:27:19 +0400 Subject: [PATCH] [java-refactorings] Change signature: parenthesized and record patterns can be deconstruction components IDEA-303509 GitOrigin-RevId: abd79e52bd0160dc5d50f10e032a12d47f9f5b5a --- .../JavaChangeSignatureUsageProcessor.java | 146 +++++++++++++----- .../JavaChangeSignatureUsageSearcher.java | 12 +- .../tree/java/PsiDeconstructionListImpl.java | 11 +- ...cordCanonicalConstructorAddParameter2.java | 22 +++ ...nonicalConstructorAddParameter2_after.java | 23 +++ .../RecordCanonicalConstructorRename2.java | 24 +++ ...cordCanonicalConstructorRename2_after.java | 24 +++ .../RecordCanonicalConstructorReorder2.java | 24 +++ ...ordCanonicalConstructorReorder2_after.java | 24 +++ .../RecordHeaderDeleteRename2.java | 18 +++ .../RecordHeaderDeleteRename2_after.java | 16 ++ .../java/refactoring/ChangeSignatureTest.java | 50 +++++- 12 files changed, 343 insertions(+), 51 deletions(-) create mode 100644 java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorAddParameter2.java create mode 100644 java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorAddParameter2_after.java create mode 100644 java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorRename2.java create mode 100644 java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorRename2_after.java create mode 100644 java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorReorder2.java create mode 100644 java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorReorder2_after.java create mode 100644 java/java-tests/testData/refactoring/changeSignature/RecordHeaderDeleteRename2.java create mode 100644 java/java-tests/testData/refactoring/changeSignature/RecordHeaderDeleteRename2_after.java diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl-refactorings/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java index 1b896ef40430..6b76ed68a3bd 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java @@ -876,7 +876,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } } - abstract static class Processor { + abstract static class Processor { protected final @NotNull PsiElementFactory myFactory; protected final @NotNull Parent myParent; protected final @NotNull JavaChangeInfo myChangeInfo; @@ -952,14 +952,14 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } } - final static class RecordHeaderProcessor extends Processor { + final static class RecordHeaderProcessor extends Processor { RecordHeaderProcessor(@NotNull JavaChangeInfo changeInfo, @NotNull PsiElementFactory factory, @NotNull PsiRecordHeader header) { super(changeInfo, factory, header); } @Override - void processNew(JavaParameterInfo info, List result) { + void processNew(JavaParameterInfo info, List result) { PsiType newType = info.createType(myParent); if (newType != null) { String componentText = newType.getCanonicalText() + " " + info.getName(); @@ -967,22 +967,23 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr if (dummyComponents.length != 1) { throw new IncorrectOperationException(componentText + " is not a valid component"); } - result.add(dummyComponents[0]); + result.add(new Variable(dummyComponents[0])); } } @Override - PsiRecordComponent getChild(int index) { - return myParent.getRecordComponents()[index]; + Variable getChild(int index) { + return new Variable(myParent.getRecordComponents()[index]); } @Override - protected void process(@NotNull List newElements) { - ChangeSignatureUtil.synchronizeList(myParent, newElements, RecordHeader.INSTANCE, myChangeInfo.toRemoveParm()); + protected void process(@NotNull List newElements) { + final List newComponents = ContainerUtil.map(newElements, element -> (PsiRecordComponent)element.getElement()); + ChangeSignatureUtil.synchronizeList(myParent, newComponents, RecordHeader.INSTANCE, myChangeInfo.toRemoveParm()); } } - final static class MethodParamsProcessor extends Processor { + final static class MethodParamsProcessor extends Processor { private final @Nullable PsiElement myMethodBody; private final @NotNull PsiSubstitutor mySubstitutor; private final @Nullable PsiMethod myBaseMethod; @@ -1000,20 +1001,20 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } @Override - void processNew(JavaParameterInfo info, List result) { + void processNew(JavaParameterInfo info, List result) { PsiElement parent = myParent.getParent(); if (parent instanceof PsiLambdaExpression && !((PsiLambdaExpression)parent).hasFormalParameterTypes()) { PsiExpression dummyLambdaParam = myFactory.createExpressionFromText(info.getName() + "-> {}", myParent); - result.add(((PsiLambdaExpression)dummyLambdaParam).getParameterList().getParameters()[0]); + result.add(new Variable(((PsiLambdaExpression)dummyLambdaParam).getParameterList().getParameters()[0])); } else { - result.add(createNewParameter(myChangeInfo, info, mySubstitutor)); + result.add(new Variable(createNewParameter(myChangeInfo, info, mySubstitutor))); } } @Override - PsiParameter getChild(int index) { - return myParent.getParameter(index); + Variable getChild(int index) { + return new Variable(Objects.requireNonNull(myParent.getParameter(index))); } @Override @@ -1032,13 +1033,15 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } @Override - protected void process(@NotNull List newElements) { - resolveVariableVsFieldsConflicts(newElements, newElements, myParent, myChangeInfo.toRemoveParm(), myMethodBody, - ParameterList.INSTANCE); + protected void process(@NotNull List newElements) { + final List newParameters = ContainerUtil.map(newElements, element -> (PsiParameter)element.getElement()); + final List newParameterNames = ContainerUtil.map(newElements, Variable::getName); + final boolean[] toRemove = myChangeInfo.toRemoveParm(); + resolveVariableVsFieldsConflicts(newParameters, newParameterNames, myParent, toRemove, myMethodBody, ParameterList.INSTANCE); } } - final static class DeconstructionProcessor extends Processor { + final static class DeconstructionProcessor extends Processor { DeconstructionProcessor(@NotNull JavaChangeInfo changeInfo, @NotNull PsiElementFactory factory, @NotNull PsiDeconstructionList list) { @@ -1046,31 +1049,31 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } @Override - void processNew(JavaParameterInfo info, List result) { + void processNew(JavaParameterInfo info, List result) { PsiType newType = info.createType(myParent); if (newType != null) { String patternText = newType.getCanonicalText() + " " + info.getName(); PsiExpression expression = myFactory.createExpressionFromText("x instanceof " + patternText, null); - if (!(expression instanceof PsiInstanceOfExpression)) { + if (!(expression instanceof PsiInstanceOfExpression instanceOfExpression)) { throw new IncorrectOperationException(patternText + " is not a valid pattern"); } - PsiPattern pattern = ((PsiInstanceOfExpression)expression).getPattern(); - if (!(pattern instanceof PsiTypeTestPattern)) { - throw new IncorrectOperationException(patternText + " is not a valid pattern"); - } - result.add(((PsiTypeTestPattern)pattern).getPatternVariable()); + PsiPattern pattern = instanceOfExpression.getPattern(); + result.add(new Pattern(Objects.requireNonNull(pattern))); } } @Override - PsiPatternVariable getChild(int index) { - PsiPattern pattern = myParent.getDeconstructionComponents()[index]; - return pattern instanceof PsiTypeTestPattern ? ((PsiTypeTestPattern)pattern).getPatternVariable() : null; + Pattern getChild(int index) { + return new Pattern(myParent.getDeconstructionComponents()[index]); } @Override - protected void process(@NotNull List newElements) { - resolveVariableVsFieldsConflicts(newElements, ContainerUtil.map(newElements, variable -> (PsiPattern)variable.getParent()), myParent, + protected void process(@NotNull List elements) { + final List newPatterns = ContainerUtil.map(elements, element -> (PsiPattern)element.getElement()); + final List newElementNames = ContainerUtil.map(elements, Pattern::getName); + resolveVariableVsFieldsConflicts(newPatterns, + newElementNames, + myParent, myChangeInfo.toRemoveParm(), PsiTreeUtil.getParentOfType(myParent, PsiStatement.class), DeconstructionList.INSTANCE); @@ -1110,7 +1113,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } boolean[] toRemoveParm = new boolean[newParameters.size()]; Arrays.fill(toRemoveParm, false); - resolveVariableVsFieldsConflicts(newParameters, newParameters, caller.getParameterList(), toRemoveParm, caller.getBody(), + final List newParameterNames = ContainerUtil.map(newParameters, parameter -> parameter.getName()); + resolveVariableVsFieldsConflicts(newParameters, newParameterNames, caller.getParameterList(), toRemoveParm, caller.getBody(), ParameterList.INSTANCE); } @@ -1220,8 +1224,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr } private static void resolveVariableVsFieldsConflicts( - final List newVariables, final List newElements, + final List newElementNames, final Parent parent, boolean[] toRemoveParm, final PsiElement methodBody, @@ -1229,8 +1233,8 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr { PsiUtilCore.ensureValid(parent); List conflictResolvers = new ArrayList<>(); - for (PsiVariable newVariable : newVariables) { - conflictResolvers.add(new FieldConflictsResolver(newVariable.getName(), methodBody)); + for (String newElementName : ContainerUtil.skipNulls(newElementNames)) { + conflictResolvers.add(new FieldConflictsResolver(newElementName, methodBody)); } ChangeSignatureUtil.synchronizeList(parent, newElements, generator, toRemoveParm); LOG.assertTrue(parent.getContainingFile() != null, "No containing file for: " + parent.getClass()); @@ -1384,7 +1388,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr PsiStatement firstStmt = statements.length > 0 ? statements[0] : null; if (firstStmt instanceof PsiExpressionStatement) { PsiExpression call = ((PsiExpressionStatement)firstStmt).getExpression(); - if (call instanceof PsiMethodCallExpression && + if (call instanceof PsiMethodCallExpression && MethodCallUtils.isSuperMethodCall((PsiMethodCallExpression)call, method)) { return (PsiMethodCallExpression)call; } @@ -1583,4 +1587,76 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr catch (ContractConverter.ContractConversionException ignored) { } } + + interface ChildI { + @Nullable String getName(); + @Nullable PsiElement getNameIdentifier(); + @Nullable PsiTypeElement getTypeElement(); + @NotNull PsiElement getElement(); + default void normalizeDeclaration() {} + } + + final static class Variable implements ChildI { + private final @NotNull PsiVariable myElement; + + Variable(@NotNull PsiVariable element) { + myElement = element; + } + + @Override + public String getName() { + return myElement.getName(); + } + + @Override + public @Nullable PsiElement getNameIdentifier() { + return myElement.getNameIdentifier(); + } + + @Override + public PsiTypeElement getTypeElement() { + return myElement.getTypeElement(); + } + + @Override + public @NotNull PsiElement getElement() { + return myElement; + } + + @Override + public void normalizeDeclaration() { + myElement.normalizeDeclaration(); + } + } + + final static class Pattern implements ChildI { + private final @NotNull PsiPattern myElement; + + Pattern(@NotNull PsiPattern element) { + myElement = element; + } + + @Override + @Nullable + public String getName() { + final PsiPatternVariable variable = JavaPsiPatternUtil.getPatternVariable(myElement); + return variable != null ? variable.getName() : null; + } + + @Override + public @Nullable PsiElement getNameIdentifier() { + final PsiPatternVariable variable = JavaPsiPatternUtil.getPatternVariable(myElement); + return variable != null ? variable.getNameIdentifier() : null; + } + + @Override + public @Nullable PsiTypeElement getTypeElement() { + return JavaPsiPatternUtil.getPatternTypeElement(myElement); + } + + @Override + public @NotNull PsiElement getElement() { + return myElement; + } + } } diff --git a/java/java-impl-refactorings/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java b/java/java-impl-refactorings/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java index 90fe001eba94..079a485217f0 100644 --- a/java/java-impl-refactorings/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java +++ b/java/java-impl-refactorings/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageSearcher.java @@ -108,12 +108,8 @@ class JavaChangeSignatureUsageSearcher { return false; } for (int i = 0; i < components.length; i++) { - PsiPattern component = components[i]; - if (!(component instanceof PsiTypeTestPattern)) { - return false; - } - PsiPatternVariable patternVar = ((PsiTypeTestPattern)component).getPatternVariable(); - if (patternVar == null || !patternVar.getType().equals(parameters[i].getType())) { + PsiType type = JavaPsiPatternUtil.getPatternType(components[i]); + if (!parameters[i].getType().equals(type)) { return false; } } @@ -296,8 +292,8 @@ class JavaChangeSignatureUsageSearcher { if (RefactoringUtil.isMethodUsage(element)) { PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(element); if (list == null || !method.isVarArgs() && list.getExpressionCount() != parameterCount) continue; - if (method.isVarArgs() && - ref instanceof PsiReferenceExpression && + if (method.isVarArgs() && + ref instanceof PsiReferenceExpression && !((PsiReferenceExpression)ref).advancedResolve(true).isValidResult()) { continue; } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiDeconstructionListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiDeconstructionListImpl.java index 32916f868864..74dc23ee22d5 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiDeconstructionListImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiDeconstructionListImpl.java @@ -4,7 +4,6 @@ package com.intellij.psi.impl.source.tree.java; import com.intellij.lang.ASTNode; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.CompositePsiElement; -import com.intellij.psi.impl.source.tree.JavaElementType; import com.intellij.psi.impl.source.tree.JavaSourceUtil; import com.intellij.psi.impl.source.tree.TreeElement; import com.intellij.psi.scope.PsiScopeProcessor; @@ -13,10 +12,10 @@ import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.intellij.psi.impl.source.tree.JavaElementType.DECONSTRUCTION_LIST; +import static com.intellij.psi.impl.source.tree.JavaElementType.*; public class PsiDeconstructionListImpl extends CompositePsiElement implements PsiDeconstructionList { - private final TokenSet TYPE_TEST_PATTERN_SET = TokenSet.create(JavaElementType.TYPE_TEST_PATTERN); + private final TokenSet PRIMARY_PATTERN_SET = TokenSet.create(TYPE_TEST_PATTERN, DECONSTRUCTION_PATTERN, PARENTHESIZED_PATTERN); public PsiDeconstructionListImpl() { super(DECONSTRUCTION_LIST); @@ -34,7 +33,7 @@ public class PsiDeconstructionListImpl extends CompositePsiElement implements Ps @Override public void deleteChildInternal(@NotNull ASTNode child) { - if (child.getElementType() == JavaElementType.TYPE_TEST_PATTERN) { + if (PRIMARY_PATTERN_SET.contains(child.getElementType())) { JavaSourceUtil.deleteSeparatingComma(this, child); } @@ -56,8 +55,8 @@ public class PsiDeconstructionListImpl extends CompositePsiElement implements Ps TreeElement firstAdded = super.addInternal(first, last, anchor, before); - if (first == last && first.getElementType() == JavaElementType.TYPE_TEST_PATTERN) { - JavaSourceUtil.addSeparatingComma(this, first, TYPE_TEST_PATTERN_SET); + if (first == last && PRIMARY_PATTERN_SET.contains(first.getElementType())) { + JavaSourceUtil.addSeparatingComma(this, first, PRIMARY_PATTERN_SET); } return firstAdded; diff --git a/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorAddParameter2.java b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorAddParameter2.java new file mode 100644 index 000000000000..3e0dc782dd67 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorAddParameter2.java @@ -0,0 +1,22 @@ +/** + * @param point1 point1 + * @param point2 point2 + */ +record Rect(Point point1, Point point2) { + Rect(Point point1, Point point2) { + this.point1 = point1; + this.point2 = point2; + } +} +record Point(int y, int x) {} + +class Use { + void foo(Object obj) { + switch (obj) { + case Rect(Point point1, Point point2) when point1.equals(point2) -> {} + case Rect(Point(int y1, int x1) point1, Point(int y2, int x2)) rect when x1 == x2 -> System.out.println(point1); + case ((Rect(((Point(((int x1)), ((int y1))))), Point(((int x2)), ((int y2))) point2))) -> System.out.println(point2); + default -> throw new IllegalStateException("Unexpected value: " + obj); + } + } +} diff --git a/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorAddParameter2_after.java b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorAddParameter2_after.java new file mode 100644 index 000000000000..b05760e5ff74 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorAddParameter2_after.java @@ -0,0 +1,23 @@ +/** + * @param point1 point1 + * @param point2 point2 + * @param i + */ +record Rect(Point point1, Point point2, int i) { + Rect(Point point1, Point point2, int i) { + this.point1 = point1; + this.point2 = point2; + } +} +record Point(int y, int x) {} + +class Use { + void foo(Object obj) { + switch (obj) { + case Rect(Point point1, Point point2, int i) when point1.equals(point2) -> {} + case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1); + case ((Rect(((Point(((int x1)), ((int y1))))), Point(((int x2)), ((int y2))) point2, int i))) -> System.out.println(point2); + default -> throw new IllegalStateException("Unexpected value: " + obj); + } + } +} diff --git a/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorRename2.java b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorRename2.java new file mode 100644 index 000000000000..3889b907a4f2 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorRename2.java @@ -0,0 +1,24 @@ +/** + * @param point1 point1 + * @param point2 point2 + * @param i i + */ +record Rect(Point point1, Point point2, int i) { + Rect(Point point1, Point point2, int i) { + this.point1 = point1; + this.point2 = point2; + this.i = i; + } +} +record Point(int y, int x) {} + +class Use { + void foo(Object obj) { + switch (obj) { + case Rect(Point point1, Point point2, int i) when point1.equals(point2) -> {} + case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1); + case ((Rect(((Point(((int x1)), ((int y1))))), Point(((int x2)), ((int y2))) point2, ((int i))))) -> System.out.println(point2); + default -> throw new IllegalStateException("Unexpected value: " + obj); + } + } +} diff --git a/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorRename2_after.java b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorRename2_after.java new file mode 100644 index 000000000000..6b17e86f78ad --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorRename2_after.java @@ -0,0 +1,24 @@ +/** + * @param point2 point2 + * @param point1 point1 + * @param i i + */ +record Rect(Point point2, Point point1, int i) { + Rect(Point point2, Point point1, int i) { + this.point2 = point2; + this.point1 = point1; + this.i = i; + } +} +record Point(int y, int x) {} + +class Use { + void foo(Object obj) { + switch (obj) { + case Rect(Point point2, Point point1, int i) when point2.equals(point1) -> {} + case Rect(Point(int y1, int x1) point2, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point2); + case ((Rect(((Point(((int x1)), ((int y1))))), Point(((int x2)), ((int y2))) point1, ((int i))))) -> System.out.println(point1); + default -> throw new IllegalStateException("Unexpected value: " + obj); + } + } +} diff --git a/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorReorder2.java b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorReorder2.java new file mode 100644 index 000000000000..4f35e9ef0fd9 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorReorder2.java @@ -0,0 +1,24 @@ +/** + * @param point1 point1 + * @param point2 point2 + * @param i i + */ +record Rect(Point point1, Point point2, int i) { + Rect(Point point1, Point point2, int i) { + this.point1 = point1; + this.point2 = point2; + this.i = i; + } +} +record Point(int y, int x) {} + +class Use { + void foo(Object obj) { + switch (obj) { + case Rect(Point point1, Point point2, int i) when point1.equals(point2) -> {} + case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1); + case ((Rect(((Point(((int x1)), ((int y1))))), Point(((int x2)), ((int y2))) point2, ((int i))))) -> System.out.println(point2); + default -> {} + } + } +} diff --git a/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorReorder2_after.java b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorReorder2_after.java new file mode 100644 index 000000000000..6a0d56612443 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/RecordCanonicalConstructorReorder2_after.java @@ -0,0 +1,24 @@ +/** + * @param i i + * @param point2 point2 + * @param point1 point1 + */ +record Rect(int i, Point point2, Point point1) { + Rect(int i, Point point2, Point point1) { + this.point1 = point1; + this.point2 = point2; + this.i = i; + } +} +record Point(int y, int x) {} + +class Use { + void foo(Object obj) { + switch (obj) { + case Rect(int i, Point point2, Point point1) when point1.equals(point2) -> {} + case Rect(int i, Point(int y2, int x2), Point(int y1, int x1) point1) rect when x1 == x2 -> System.out.println(point1); + case ((Rect(((int i)), Point(((int x2)), ((int y2))) point2, ((Point(((int x1)), ((int y1)))))))) -> System.out.println(point2); + default -> {} + } + } +} diff --git a/java/java-tests/testData/refactoring/changeSignature/RecordHeaderDeleteRename2.java b/java/java-tests/testData/refactoring/changeSignature/RecordHeaderDeleteRename2.java new file mode 100644 index 000000000000..a4ad00f4c733 --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/RecordHeaderDeleteRename2.java @@ -0,0 +1,18 @@ +/** + * @param point1 point1 + * @param point2 point2 + * @param i i + */ +record Rect(Point point1, Point point2, int i) {} +record Point(int y, int x) {} + +class Use { + void foo(Object obj) { + switch (obj) { + case Rect(Point point1, Point point2, int i) when point2.x() == 42 -> System.out.println(point2); + case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1); + case ((Rect(((Point(((int x1)), ((int y1))))), ((Point(((int x2)), ((int y2))) point2)), ((int i))))) -> System.out.println(point2); + default -> throw new IllegalStateException("Unexpected value: " + obj); + } + } +} diff --git a/java/java-tests/testData/refactoring/changeSignature/RecordHeaderDeleteRename2_after.java b/java/java-tests/testData/refactoring/changeSignature/RecordHeaderDeleteRename2_after.java new file mode 100644 index 000000000000..74ca8db51aee --- /dev/null +++ b/java/java-tests/testData/refactoring/changeSignature/RecordHeaderDeleteRename2_after.java @@ -0,0 +1,16 @@ +/** + * @param p2 point2 + */ +record Rect(Point p2) {} +record Point(int y, int x) {} + +class Use { + void foo(Object obj) { + switch (obj) { + case Rect(Point p2) when p2.x() == 42 -> System.out.println(p2); + case Rect(Point(int y2, int x2)) rect when x1 == x2 -> System.out.println(point1); + case ((Rect(((Point(((int x2)), ((int y2))) p2))))) -> System.out.println(p2); + default -> throw new IllegalStateException("Unexpected value: " + obj); + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/ChangeSignatureTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/ChangeSignatureTest.java index ff7f0abfb747..e839a5ce20b8 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/ChangeSignatureTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ChangeSignatureTest.java @@ -541,7 +541,17 @@ public class ChangeSignatureTest extends ChangeSignatureBaseTest { }; }, false); } - + + public void testRecordHeaderDeleteRename2() { + final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); + final PsiType pointType = facade.getElementFactory().createTypeFromText("Point", null); + doTest(null, null, null, method -> { + return new ParameterInfoImpl[]{ + ParameterInfoImpl.create(1).withName("p2").withType(pointType) + }; + }, false); + } + public void testRecordCanonicalConstructorRename() { doTest(null, null, null, method -> { return new ParameterInfoImpl[]{ @@ -551,6 +561,18 @@ public class ChangeSignatureTest extends ChangeSignatureBaseTest { }; }, false); } + + public void testRecordCanonicalConstructorRename2() { + final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); + final PsiType pointType = facade.getElementFactory().createTypeFromText("Point", null); + doTest(null, null, null, method -> { + return new ParameterInfoImpl[]{ + ParameterInfoImpl.create(0).withName("point2").withType(pointType), + ParameterInfoImpl.create(1).withName("point1").withType(pointType), + ParameterInfoImpl.create(2).withName("i").withType(PsiType.INT) + }; + }, false); + } public void testRecordCanonicalConstructorReorder() { doTest(null, null, null, method -> { @@ -561,7 +583,19 @@ public class ChangeSignatureTest extends ChangeSignatureBaseTest { }; }, false); } - + + public void testRecordCanonicalConstructorReorder2() { + final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); + final PsiType pointType = facade.getElementFactory().createTypeFromText("Point", null); + doTest(null, null, null, method -> { + return new ParameterInfoImpl[]{ + ParameterInfoImpl.create(2).withName("i").withType(PsiType.INT), + ParameterInfoImpl.create(1).withName("point2").withType(pointType), + ParameterInfoImpl.create(0).withName("point1").withType(pointType), + }; + }, false); + } + public void testRecordCanonicalConstructorAddParameter() { doTest(null, null, null, method -> { return new ParameterInfoImpl[]{ @@ -570,6 +604,18 @@ public class ChangeSignatureTest extends ChangeSignatureBaseTest { }; }, false); } + + public void testRecordCanonicalConstructorAddParameter2() { + final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); + final PsiType pointType = facade.getElementFactory().createTypeFromText("Point", null); + doTest(null, null, null, method -> { + return new ParameterInfoImpl[]{ + ParameterInfoImpl.create(0).withName("point1").withType(pointType), + ParameterInfoImpl.create(1).withName("point2").withType(pointType), + ParameterInfoImpl.create(-1).withName("i").withType(PsiType.INT) + }; + }, false); + } public void testRecordComponentWithImportToBeAdded() { doTest(null, null, null, method -> {