diff --git a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java index aa6f8f3ce249..72d44dc9fb00 100644 --- a/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/copy/CopyClassesHandler.java @@ -403,7 +403,11 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { } } for (PsiElement expression : rebindExpressions) { - codeStyleManager.shortenClassReferences(expression); + //filter out invalid elements which are produced by nested elements: + //new expressions/type elements, like: List>; new Foo(new Foo()), etc + if (expression.isValid()){ + codeStyleManager.shortenClassReferences(expression); + } } new OptimizeImportsProcessor(project, createdFiles.toArray(new PsiFile[createdFiles.size()]), null).run(); return createdFiles; @@ -496,20 +500,20 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase { @Override public void visitNewExpression(PsiNewExpression expression) { + super.visitNewExpression(expression); final PsiJavaCodeReferenceElement referenceElement = expression.getClassReference(); if (referenceElement != null) { decodeRef(referenceElement, oldToNewMap, rebindMap); } - super.visitNewExpression(expression); } @Override public void visitTypeElement(PsiTypeElement type) { + super.visitTypeElement(type); final PsiJavaCodeReferenceElement referenceElement = type.getInnermostComponentReferenceElement(); if (referenceElement != null) { decodeRef(referenceElement, oldToNewMap, rebindMap); } - super.visitTypeElement(type); } }); for (Map.Entry entry : rebindMap.entrySet()) { diff --git a/java/java-tests/testData/refactoring/copyClass/recursiveTypes/Bar.expected.java b/java/java-tests/testData/refactoring/copyClass/recursiveTypes/Bar.expected.java new file mode 100644 index 000000000000..0299213e19cd --- /dev/null +++ b/java/java-tests/testData/refactoring/copyClass/recursiveTypes/Bar.expected.java @@ -0,0 +1,8 @@ +public class Bar { + public Bar(Bar f) { + } + + Bar> foos() { + return new Bar>(new Bar>(null)); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/copyClass/recursiveTypes/Foo.java b/java/java-tests/testData/refactoring/copyClass/recursiveTypes/Foo.java new file mode 100644 index 000000000000..68f63a94dd59 --- /dev/null +++ b/java/java-tests/testData/refactoring/copyClass/recursiveTypes/Foo.java @@ -0,0 +1,8 @@ +public class Foo { + public Foo(Foo f) { + } + + Foo> foos() { + return new Foo>(new Foo>(null)); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/CopyClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/CopyClassTest.java index 1770e841fe8c..3e8fc36b0139 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/CopyClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/CopyClassTest.java @@ -53,6 +53,10 @@ public class CopyClassTest extends CodeInsightTestCase { doTest("Foo", "Bar"); } + public void testRecursiveTypes() throws Exception { + doTest("Foo", "Bar"); + } + public void testLibraryClass() throws Exception { // IDEADEV-28791 JavaCodeStyleSettings javaSettings = getCurrentCodeStyleSettings().getCustomSettings(JavaCodeStyleSettings.class); javaSettings.CLASS_NAMES_IN_JAVADOC = JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_ALWAYS;