From db546f6911f3fb638ef5e80852695be06647add0 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 26 Sep 2016 11:19:33 +0200 Subject: [PATCH] SSR: copy implements, extends and type parameters correctly when replacing classes with inner classes --- .../structuralsearch/JavaReplaceHandler.java | 45 +++++++++++-------- .../StructuralReplaceTest.java | 24 ++++++++-- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java b/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java index d3cd64dfa6d4..f7f1d01e3d2b 100644 --- a/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java +++ b/java/structuralsearch-java/src/com/intellij/structuralsearch/JavaReplaceHandler.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.intellij.structuralsearch; import com.intellij.openapi.fileTypes.StdFileTypes; @@ -130,7 +145,6 @@ public class JavaReplaceHandler extends StructuralReplaceHandler { * that are present in matched nodes but not present in searched & replaced nodes */ private void copyUnmatchedElements(final PsiElement original, final PsiElement replacement) { - Map newNameToSearchPatternNameMap = myContext.getNewName2PatternNameMap(); Map originalNamedElements = Collector.collectNamedElements(original); @@ -197,6 +211,18 @@ public class JavaReplaceHandler extends StructuralReplaceHandler { replacementNamedElement instanceof PsiMethod) { copyMethodBodyIfNotReplaced((PsiMethod)originalNamedElement, (PsiMethod)searchedNamedElement, (PsiMethod)replacementNamedElement); } + + if (originalNamedElement instanceof PsiClass && + searchedNamedElement instanceof PsiClass && + replacementNamedElement instanceof PsiClass) { + final PsiClass originalClass = (PsiClass)originalNamedElement; + final PsiClass queryClass = (PsiClass)searchedNamedElement; + final PsiClass replacementClass = (PsiClass)replacementNamedElement; + + copyExtendsListIfNotReplaced(originalClass, queryClass, replacementClass); + copyImplementsListIfNotReplaced(originalClass, queryClass, replacementClass); + copyTypeParameterListIfNotReplaced(originalClass, queryClass, replacementClass); + } } } @@ -361,26 +387,9 @@ public class JavaReplaceHandler extends StructuralReplaceHandler { elementToReplace.getNode().getTreeParent().removeChild(elementToReplace.getNode()); } else { - // preserve comments copyUnmatchedElements(elementToReplace, replacement); - if (replacement instanceof PsiClass) { - final PsiStatement[] searchStatements = getCodeBlock().getStatements(); - if (searchStatements.length > 0 && - searchStatements[0] instanceof PsiDeclarationStatement && - ((PsiDeclarationStatement)searchStatements[0]).getDeclaredElements()[0] instanceof PsiClass) { - final PsiClass replaceClazz = (PsiClass)replacement; - final PsiClass queryClazz = (PsiClass)((PsiDeclarationStatement)searchStatements[0]).getDeclaredElements()[0]; - final PsiClass clazz = (PsiClass)elementToReplace; - - copyExtendsListIfNotReplaced(clazz, queryClazz, replaceClazz); - copyImplementsListIfNotReplaced(clazz, queryClazz, replaceClazz); - copyTypeParameterListIfNotReplaced(clazz, queryClazz, replaceClazz); - } - } - replacement = handleSymbolReplacement(replacement, elementToReplace); - elementToReplace.replace(replacement); } } diff --git a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java index 002045385084..0038cb39477e 100644 --- a/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java +++ b/platform/structuralsearch/testSource/com/intellij/structuralsearch/StructuralReplaceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -2455,7 +2455,8 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase { final String by = "void $a$(int i);"; assertEquals("abstract class A {\n" + " abstract void a(int i);\n" + - "}", replacer.testReplace(in, what, by, options)); + "}", + replacer.testReplace(in, what, by, options)); } public void testReplaceParameterWithComment() { @@ -2466,6 +2467,23 @@ public class StructuralReplaceTest extends StructuralReplaceTestCase { final String by = "final long /*!*/ $a$ = $b$;"; assertEquals("class A {\n" + " void a(final long /*!*/ b) {}\n" + - "}", replacer.testReplace(in, what, by, options)); + "}", + replacer.testReplace(in, what, by, options)); + } + + public void testReplaceInnerClass() { + String in = "public class A {" + + " public class B extends A implements Serializable {}" + + "}"; + String what = "class '_A {" + + " class '_B {}" + + "}"; + String by = "class $A$ {" + + " private class $B$ {}" + + "}"; + assertEquals("public class A {" + + " private class B extends A implements Serializable {}" + + "}", + replacer.testReplace(in, what, by, options)); } } \ No newline at end of file