[java-inspection] IDEA-379323 IDEA-379318 improves name generation for deconstruction patterns

GitOrigin-RevId: 43b49218eb088fb3d2bd03dd7bdeff0aaad0c6cb
This commit is contained in:
Mikhail Pyltsin
2025-09-16 11:58:39 +00:00
committed by intellij-monorepo-bot
parent c3826e657d
commit fe718e2875
6 changed files with 91 additions and 9 deletions
@@ -112,12 +112,11 @@ public final class DeconstructionCanBeUsedInspection extends AbstractBaseJavaLoc
if (instanceOf == null) return;
List<List<PsiReferenceExpression>> collect = collect(instanceOf, patternVariable, true);
StringJoiner deconstructionList = new StringJoiner(", ", "(", ")");
List<String> usedNames = new ArrayList<>();
for (List<PsiReferenceExpression> expressions : collect) {
PsiReferenceExpression firstRef = expressions.get(0);
PsiReferenceExpression firstRef = expressions.getFirst();
PsiType type = firstRef.getType();
String s = StringUtil.substringAfter(firstRef.getText(), ".");
VariableNameGenerator generator = new VariableNameGenerator(patternVariable, VariableKind.PARAMETER).byName(s);
s = generator.generate(false);
String deconstructionName = getDeconstructionName(expressions, usedNames, patternVariable);
String stringType;
if (type != null) {
//example: if (obj instanceof Example<?> example)
@@ -131,18 +130,18 @@ public final class DeconstructionCanBeUsedInspection extends AbstractBaseJavaLoc
else {
stringType = "var";
}
deconstructionList.add(stringType + " " + s);
deconstructionList.add(stringType + " " + deconstructionName);
for (PsiReferenceExpression expression : expressions) {
PsiLocalVariable variable = getVariableFromInitializer(expression);
if (variable != null) {
var references = VariableAccessUtils.getVariableReferences(variable);
for (PsiReferenceExpression ref : references) {
ExpressionUtils.bindReferenceTo(ref, s);
ExpressionUtils.bindReferenceTo(ref, deconstructionName);
}
new CommentTracker().deleteAndRestoreComments(variable);
}
else {
new CommentTracker().replace(expression.getParent() instanceof PsiMethodCallExpression call ? call : expression, s);
new CommentTracker().replace(expression.getParent() instanceof PsiMethodCallExpression call ? call : expression, deconstructionName);
}
}
}
@@ -161,6 +160,34 @@ public final class DeconstructionCanBeUsedInspection extends AbstractBaseJavaLoc
}
}
@NotNull
private static String getDeconstructionName(@NotNull List<PsiReferenceExpression> expressions,
@NotNull List<String> usedNames,
@NotNull PsiPatternVariable patternVariable) {
PsiReferenceExpression firstRef = expressions.getFirst();
PsiVariable firstVariable = null;
for (PsiReferenceExpression expression : expressions) {
PsiLocalVariable variable = getVariableFromInitializer(expression);
if (variable != null) {
firstVariable = variable;
break;
}
}
String deconstructionName = StringUtil.substringAfter(firstRef.getText(), ".");
if (firstVariable != null && firstVariable.getNameIdentifier() != null) {
deconstructionName = firstVariable.getNameIdentifier().getText();
usedNames.add(deconstructionName);
}
else {
VariableNameGenerator generator = new VariableNameGenerator(patternVariable, VariableKind.PARAMETER)
.skipNames(usedNames)
.byName(deconstructionName);
deconstructionName = generator.generate(true);
usedNames.add(deconstructionName);
}
return deconstructionName;
}
private static @Nullable PsiLocalVariable getVariableFromInitializer(PsiReferenceExpression ref) {
PsiElement parent = PsiUtil.skipParenthesizedExprUp(ref.getParent());
if (parent instanceof PsiLocalVariable variable) {
@@ -0,0 +1,15 @@
// "Replace with record pattern" "true-preview"
class X {
record R(String oldText, String newText) {
}
void patternBug(Object obj) {
if (obj instanceof R(String text, String newText1)) {
System.out.println(text);
System.out.println(newText1);
String oldText = "foo";
String newText = "bar";
}
}
}
@@ -4,8 +4,8 @@ class X {
}
void test(Object obj) {
if (obj instanceof Point(int x, int y)) {
System.out.println(x + y);
if (obj instanceof Point(int l, int m)) {
System.out.println(l + m);
}
}
}
@@ -0,0 +1,12 @@
// "Replace with record pattern" "true-preview"
class X {
record R(String oldText, String newText) {}
void patternBug(Object obj) {
if (obj instanceof R(String superText, String newText)) {
System.out.println(superText);
System.out.println(newText);
}
}
}
@@ -0,0 +1,15 @@
// "Replace with record pattern" "true-preview"
class X {
record R(String oldText, String newText) {
}
void patternBug(Object obj) {
if (obj instanceof R<caret> r) {
System.out.println(r.oldText());
System.out.println(r.newText());
String oldText = "foo";
String newText = "bar";
}
}
}
@@ -0,0 +1,13 @@
// "Replace with record pattern" "true-preview"
class X {
record R(String oldText, String newText) {}
void patternBug(Object obj) {
if (obj instanceof R<caret> r) {
String superText = r.oldText();
System.out.println(superText);
System.out.println(r.newText());
}
}
}