From cb7ac04d17e46363172e9eee1f5eb9b9276ccca7 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 16 Sep 2024 17:29:36 +0200 Subject: [PATCH] Java: handle classes without a qualified name better (IJ-CR-144804) GitOrigin-RevId: 88ee8c15122aaca6028b591d8538e18de0882643 --- .../javadoc/PsiDocMethodOrFieldRef.java | 5 ++++- .../tree/java/PsiReferenceExpressionImpl.java | 6 +++-- .../renameInplace/MethodWithJavadocRef3.java | 21 ++++++++++++++++++ .../MethodWithJavadocRef3_after.java | 21 ++++++++++++++++++ .../renameInplace/MethodWithJavadocRef4.java | 22 +++++++++++++++++++ .../MethodWithJavadocRef4_after.java | 22 +++++++++++++++++++ .../refactoring/RenameMembersInplaceTest.java | 8 +++++++ 7 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef3.java create mode 100644 java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef3_after.java create mode 100644 java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef4.java create mode 100644 java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef4_after.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java index bcb5ffca3788..ecd65dfc9707 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiDocMethodOrFieldRef.java @@ -336,8 +336,11 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo } } else if (containingClass != null && PsiTreeUtil.getParentOfType(PsiDocMethodOrFieldRef.this, PsiClass.class) != containingClass) { + String qName = containingClass.getQualifiedName(); + if (qName == null) qName = containingClass.getName(); // local class has no qualified name, but has a short name + if (qName == null) return PsiDocMethodOrFieldRef.this; // ref can't be fixed PsiDocComment fromText = JavaPsiFacade.getElementFactory(containingClass.getProject()) - .createDocCommentFromText("/**{@link " + containingClass.getQualifiedName() + "#" + newName + "}*/"); + .createDocCommentFromText("/**{@link " + qName + "#" + newName + "}*/"); PsiDocMethodOrFieldRef methodOrFieldRefFromText = PsiTreeUtil.findChildOfType(fromText, PsiDocMethodOrFieldRef.class); addAfter(Objects.requireNonNull(methodOrFieldRefFromText).getFirstChild(), null); } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java index 7ab3b9b4e958..3119d2fdba39 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java @@ -676,8 +676,10 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements PsiClass psiClass = member.getContainingClass(); if (psiClass == null) throw new IncorrectOperationException(); boolean isStatic = ((PsiMember)element).hasModifierProperty(PsiModifier.STATIC); - String qName = psiClass.getQualifiedName() + (isStatic ? "." : ".this.") + member.getName(); - PsiExpression ref = parserFacade.createExpressionFromText(qName, this); + String qName = psiClass.getQualifiedName(); + if (qName == null) qName = psiClass.getName(); // local class has no qualified name, but has a short name + if (qName == null) return this; // ref can't be fixed + PsiExpression ref = parserFacade.createExpressionFromText(qName + (isStatic ? "." : ".this.") + member.getName(), this); getTreeParent().replaceChildInternal(this, (TreeElement)ref.getNode()); return ref; } diff --git a/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef3.java b/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef3.java new file mode 100644 index 000000000000..fb8f4ca44cef --- /dev/null +++ b/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef3.java @@ -0,0 +1,21 @@ +class Main { + public static void main(String[] args) { + + interface Add { + static OptionalLong set(long a) { + return null; + } + + interface Async { + /** + * @see #set(long) + */ + CompletableFuture add(long a); + + static void x() { + set(1); + } + } + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef3_after.java b/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef3_after.java new file mode 100644 index 000000000000..5c608377f2a3 --- /dev/null +++ b/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef3_after.java @@ -0,0 +1,21 @@ +class Main { + public static void main(String[] args) { + + interface Add { + static OptionalLong set(long a) { + return null; + } + + interface Async { + /** + * @see Add#set(long) + */ + CompletableFuture set(long a); + + static void x() { + Add.set(1); + } + } + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef4.java b/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef4.java new file mode 100644 index 000000000000..080042b7ef4c --- /dev/null +++ b/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef4.java @@ -0,0 +1,22 @@ +class Main { + public static void main(String[] args) { + + new Object() { + static OptionalLong set(long a) { + return null; + } + + interface Async { + /** + * @see #set(long) + * incorrect but can't be fixed + */ + CompletableFuture add(long a); + + static void x() { + set(1); // incorrect but can't be fixed + } + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef4_after.java b/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef4_after.java new file mode 100644 index 000000000000..bbca93521111 --- /dev/null +++ b/java/java-tests/testData/refactoring/renameInplace/MethodWithJavadocRef4_after.java @@ -0,0 +1,22 @@ +class Main { + public static void main(String[] args) { + + new Object() { + static OptionalLong set(long a) { + return null; + } + + interface Async { + /** + * @see #set(long) + * incorrect but can't be fixed + */ + CompletableFuture set(long a); + + static void x() { + set(1); // incorrect but can't be fixed + } + } + }; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/RenameMembersInplaceTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/RenameMembersInplaceTest.java index fdbb1f9b241e..0a8e2d917af4 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/RenameMembersInplaceTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/RenameMembersInplaceTest.java @@ -77,6 +77,14 @@ public class RenameMembersInplaceTest extends LightJavaCodeInsightTestCase { public void testMethodWithJavadocRef2() { doTestInplaceRename("set"); } + + public void testMethodWithJavadocRef3() { + doTestInplaceRename("set"); + } + + public void testMethodWithJavadocRef4() { + doTestInplaceRename("set"); + } public void testEnumConstructor() { doTestInplaceRename("Bar");