From 9c23752f97fe11a1c6df0292e5b3396efe66caa9 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Fri, 12 Oct 2012 07:47:09 +0300 Subject: [PATCH] Groovy: 'normalize implements/extends lists' --- .../groovy/annotator/GroovyAnnotator.java | 103 +++++------ .../ChangeExtendsImplementsQuickFix.java | 162 +++++++----------- .../intentions/ExtendsImplementsFix.java | 108 ------------ .../ImplementsExtendsQuickFixTest.groovy | 53 ++++++ .../ImplementsExtendsQuickFixTest.java | 61 ------- .../groovy/extendsImplementsFix/implExt2.test | 2 - .../extendsImplementsFix/interface1.test | 2 +- 7 files changed, 161 insertions(+), 330 deletions(-) delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/ExtendsImplementsFix.java create mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/implExtQuickFix/ImplementsExtendsQuickFixTest.groovy delete mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/implExtQuickFix/ImplementsExtendsQuickFixTest.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index 2ee048606d6d..487fcaf9321f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -318,22 +318,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { checkConstructors(myHolder, typeDefinition); } - private static void checkReferenceList(AnnotationHolder holder, - GrReferenceList list, - boolean interfaceExpected, - String message, - @Nullable IntentionAction fix) { - if (list == null) return; - for (GrCodeReferenceElement refElement : list.getReferenceElements()) { - final PsiElement psiClass = refElement.resolve(); - if (psiClass instanceof PsiClass && ((PsiClass)psiClass).isInterface() != interfaceExpected) { - if (fix != null) { - holder.createErrorAnnotation(refElement, message).registerFix(fix); - } - } - } - } - private static void checkConstructors(AnnotationHolder holder, GrTypeDefinition typeDefinition) { if (typeDefinition.isEnum() || typeDefinition.isInterface() || typeDefinition.isAnonymous()) return; final PsiClass superClass = typeDefinition.getSuperClass(); @@ -1329,6 +1313,49 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { checkAnnotationList(myHolder, importStatement.getAnnotationList(), GroovyBundle.message("import.statement.cannot.have.modifiers")); } + @Override + public void visitExtendsClause(GrExtendsClause extendsClause) { + GrTypeDefinition typeDefinition = (GrTypeDefinition)extendsClause.getParent(); + + if (typeDefinition.isInterface()) { + checkReferenceList(myHolder, extendsClause, true, GroovyBundle.message("no.class.expected.here"), null); + } + else { + checkReferenceList(myHolder, extendsClause, false, GroovyBundle.message("no.interface.expected.here"), new ChangeExtendsImplementsQuickFix(typeDefinition)); + } + + checkForWildCards(myHolder, extendsClause); + } + + @Override + public void visitImplementsClause(GrImplementsClause implementsClause) { + GrTypeDefinition typeDefinition = (GrTypeDefinition)implementsClause.getParent(); + + if (typeDefinition.isInterface()) { + myHolder.createErrorAnnotation(implementsClause, GroovyBundle.message("no.implements.clause.allowed.for.interface")); + } + else { + checkReferenceList(myHolder, implementsClause, true, GroovyBundle.message("no.class.expected.here"), new ChangeExtendsImplementsQuickFix(typeDefinition)); + } + + checkForWildCards(myHolder, implementsClause); + } + + private static void checkReferenceList(@NotNull AnnotationHolder holder, + @NotNull GrReferenceList list, + boolean interfaceExpected, + @NotNull String message, + @Nullable IntentionAction fix) { + for (GrCodeReferenceElement refElement : list.getReferenceElements()) { + final PsiElement psiClass = refElement.resolve(); + if (psiClass instanceof PsiClass && ((PsiClass)psiClass).isInterface() != interfaceExpected) { + if (fix != null) { + holder.createErrorAnnotation(refElement, message).registerFix(fix); + } + } + } + } + private static void checkFlowInterruptStatement(GrFlowInterruptingStatement statement, AnnotationHolder holder) { final PsiElement label = statement.getLabelIdentifier(); @@ -1669,30 +1696,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { } } - final GrImplementsClause implementsClause = typeDefinition.getImplementsClause(); - final GrExtendsClause extendsClause = typeDefinition.getExtendsClause(); - - - if (typeDefinition.isInterface()) { - checkReferenceList(holder, extendsClause, true, GroovyBundle.message("no.interface.expected.here"), null); - if (implementsClause != null) { - holder.createErrorAnnotation(implementsClause, GroovyBundle.message("no.implements.clause.allowed.for.interface")); - } - } - else { - checkReferenceList(holder, extendsClause, false, GroovyBundle.message("no.interface.expected.here"), - ExtendsImplementsFix.MOVE_TO_IMPLEMENTS_LIST); - checkReferenceList(holder, implementsClause, true, GroovyBundle.message("no.class.expected.here"), - ExtendsImplementsFix.MOVE_TO_EXTENDS_LIST); - } - - if (extendsClause != null) { - checkForExtendingInterface(holder, extendsClause, implementsClause, ((GrTypeDefinition)extendsClause.getParent())); - } - - checkForWildCards(holder, extendsClause); - checkForWildCards(holder, implementsClause); - checkDuplicateClass(typeDefinition, holder); checkCyclicInheritance(holder, typeDefinition); @@ -1758,8 +1761,8 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { } final String qName = typeDefinition.getQualifiedName(); if (qName != null) { - final PsiClass[] classes = - JavaPsiFacade.getInstance(typeDefinition.getProject()).findClasses(qName, typeDefinition.getResolveScope()); + JavaPsiFacade facade = JavaPsiFacade.getInstance(typeDefinition.getProject()); + final PsiClass[] classes = facade.findClasses(qName, typeDefinition.getResolveScope()); if (classes.length > 1) { String packageName = getPackageName(typeDefinition); @@ -1789,22 +1792,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { return allClasses.length == 2 && (allClasses[0] instanceof GroovyScriptClass || allClasses[1] instanceof GroovyScriptClass); } - private static void checkForExtendingInterface(AnnotationHolder holder, - GrExtendsClause extendsClause, - GrImplementsClause implementsClause, - GrTypeDefinition myClass) { - for (GrCodeReferenceElement ref : extendsClause.getReferenceElements()) { - final PsiElement clazz = ref.resolve(); - if (clazz == null) continue; - - if (myClass.isInterface() && clazz instanceof PsiClass && !((PsiClass)clazz).isInterface()) { - final Annotation annotation = holder.createErrorAnnotation(ref, GroovyBundle.message("class.is.not.expected.here")); - annotation.registerFix(new ChangeExtendsImplementsQuickFix(extendsClause, implementsClause)); - } - } - } - - public static class DuplicateVariablesProcessor extends PropertyResolverProcessor { private boolean myBorderPassed; private final boolean myHasVisibilityModifier; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/ChangeExtendsImplementsQuickFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/ChangeExtendsImplementsQuickFix.java index 943e84264f4b..75d31e16e350 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/ChangeExtendsImplementsQuickFix.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/ChangeExtendsImplementsQuickFix.java @@ -16,13 +16,11 @@ package org.jetbrains.plugins.groovy.annotator.intentions; import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.lang.ASTNode; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,8 +33,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrImplements import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; +import java.util.Collection; +import java.util.LinkedHashSet; import java.util.Set; -import java.util.TreeSet; /** * User: Dmitry.Krasilschikov @@ -47,19 +46,13 @@ public class ChangeExtendsImplementsQuickFix implements IntentionAction { private final GrExtendsClause myExtendsClause; @Nullable private final GrImplementsClause myImplementsClause; + @NotNull + private final GrTypeDefinition myClass; - final GrTypeDefinition myClass; - - public ChangeExtendsImplementsQuickFix(GrExtendsClause extendsClause, GrImplementsClause implementsClause) { - myExtendsClause = extendsClause; - myImplementsClause = implementsClause; - - if (myImplementsClause != null) { - myClass = (GrTypeDefinition) myImplementsClause.getParent(); - } else { - assert myExtendsClause != null; - myClass = (GrTypeDefinition) myExtendsClause.getParent(); - } + public ChangeExtendsImplementsQuickFix(@NotNull GrTypeDefinition aClass) { + myClass = aClass; + myExtendsClause = aClass.getExtendsClause(); + myImplementsClause = aClass.getImplementsClause(); } @NotNull @@ -73,113 +66,82 @@ public class ChangeExtendsImplementsQuickFix implements IntentionAction { } public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - return myClass != null && myClass.isValid() && myClass.getManager().isInProject(file); + return myClass.isValid() && myClass.getManager().isInProject(file); } public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - GrCodeReferenceElement[] extendsReferenceElements = GrCodeReferenceElement.EMPTY_ARRAY; - GrCodeReferenceElement[] implementsReferenceElements = GrCodeReferenceElement.EMPTY_ARRAY; + Set classes = new LinkedHashSet(); + Set interfaces = new LinkedHashSet(); + Set unknownClasses = new LinkedHashSet(); + Set unknownInterfaces = new LinkedHashSet(); + if (myExtendsClause != null) { - extendsReferenceElements = myExtendsClause.getReferenceElements(); + collectRefs(myExtendsClause.getReferenceElements(), classes, interfaces, myClass.isInterface() ? unknownInterfaces : unknownClasses); + myExtendsClause.delete(); } if (myImplementsClause != null) { - implementsReferenceElements = myImplementsClause.getReferenceElements(); + collectRefs(myImplementsClause.getReferenceElements(), classes, interfaces, unknownInterfaces); + myImplementsClause.delete(); } - Set classes = new TreeSet(); - Set interfaces = new TreeSet(); - - for (GrCodeReferenceElement extendsReferenceElement : extendsReferenceElements) { - final PsiElement extendsElement = extendsReferenceElement.resolve(); - if (!(extendsElement instanceof PsiClass)) continue; - - if (myClass.isInterface() && !((PsiClass) extendsElement).isInterface()) continue; - - if (myClass.isInterface()) { - if (((PsiClass) extendsElement).isInterface()) { - classes.add(extendsReferenceElement.getCanonicalText()); - } - } else { - if (((PsiClass) extendsElement).isInterface()) { - interfaces.add(extendsReferenceElement.getCanonicalText()); - } else { - classes.add(extendsReferenceElement.getCanonicalText()); - } - } -// if (((PsiClass) extendsElement).isInterface()) { -// interfaces.add(extendsReferenceElement.getCanonicalText()); -// } else { -// classes.add(extendsReferenceElement.getCanonicalText()); -// } + if (myClass.isInterface()) { + interfaces.addAll(classes); + unknownInterfaces.addAll(unknownClasses); + addNewClause(interfaces, unknownInterfaces, project, true); } - - for (GrCodeReferenceElement implementsReferenceElement : implementsReferenceElements) { - //interface cannot implement anything - - final PsiElement implementsElement = implementsReferenceElement.resolve(); - if (!(implementsElement instanceof PsiClass)) continue; - - if (myClass.isInterface()) { - if (((PsiClass) implementsElement).isInterface()) { - classes.add(implementsReferenceElement.getCanonicalText()); - } - } else { - if (((PsiClass) implementsElement).isInterface()) { - interfaces.add(implementsReferenceElement.getCanonicalText()); - } else { - classes.add(implementsReferenceElement.getCanonicalText()); - } - } + else { + addNewClause(classes, unknownClasses, project, true); + addNewClause(interfaces, unknownInterfaces, project, false); } - - if (myExtendsClause != null) { - final ASTNode extendsClauseNode = myExtendsClause.getNode(); - extendsClauseNode.getTreeParent().removeChild(extendsClauseNode); - } - - if (myImplementsClause != null) { - final ASTNode implClauseNode = myImplementsClause.getNode(); - implClauseNode.getTreeParent().removeChild(implClauseNode); - } - - if (!classes.isEmpty()) { - addNewClause(classes, project, true); - } - - if (!interfaces.isEmpty()) { - addNewClause(interfaces, project, false); - } - - CodeStyleManager.getInstance(project).reformatText(myClass.getContainingFile(), - myClass.getTextRange().getStartOffset(), myClass.getBody().getTextOffset() + 2); } - private void addNewClause(Set elements, Project project, boolean isExtends) throws IncorrectOperationException { - String classText = "class A " + (isExtends ? "extends " : "implements "); + private static void collectRefs(GrCodeReferenceElement[] refs, Collection classes, Collection interfaces, Collection unknown) { + for (GrCodeReferenceElement ref : refs) { + final PsiElement extendsElement = ref.resolve(); + String canonicalText = ref.getCanonicalText(); - boolean first = true; + if (extendsElement instanceof PsiClass) { + if (((PsiClass)extendsElement).isInterface()) { + interfaces.add(canonicalText); + } + else { + classes.add(canonicalText); + } + } + else { + unknown.add(canonicalText); + } + } + } + + private void addNewClause(Collection elements, Collection additional, Project project, boolean isExtends) throws IncorrectOperationException { + if (elements.isEmpty() && additional.isEmpty()) return; + + StringBuilder classText = new StringBuilder(); + classText.append("class A "); + classText.append(isExtends ? "extends " : "implements "); for (String str : elements) { - if (!first) classText += ", "; - classText += str; - first = false; + classText.append(str); + classText.append(", "); } -// for (int i = 0; i < elements.size(); i++) { -// if (i > 0) classText += ", "; -// -// classText += elements.get(i); -// } + for (String str : additional) { + classText.append(str); + classText.append(", "); + } - classText += " {}"; + classText.delete(classText.length() - 2, classText.length()); - final GrTypeDefinition definition = GroovyPsiElementFactory.getInstance(project).createTypeDefinition(classText); + classText.append(" {}"); + + final GrTypeDefinition definition = GroovyPsiElementFactory.getInstance(project).createTypeDefinition(classText.toString()); GroovyPsiElement clause = isExtends ? definition.getExtendsClause() : definition.getImplementsClause(); - assert clause != null; - myClass.getNode().addChild(clause.getNode(), myClass.getBody().getNode()); - GrReferenceAdjuster.shortenReferences(clause); + + PsiElement addedClause = myClass.addBefore(clause, myClass.getBody()); + GrReferenceAdjuster.shortenReferences(addedClause); } public boolean startInWriteAction() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/ExtendsImplementsFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/ExtendsImplementsFix.java deleted file mode 100644 index e9ee9ed4dcf4..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/ExtendsImplementsFix.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2000-2010 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 org.jetbrains.plugins.groovy.annotator.intentions; - -import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiReference; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.GroovyBundle; -import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; -import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrReferenceList; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; -import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; -import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; - -/** - * @author Maxim.Medvedev - */ -public class ExtendsImplementsFix implements IntentionAction { - public static final ExtendsImplementsFix MOVE_TO_EXTENDS_LIST = new ExtendsImplementsFix(true); - public static final ExtendsImplementsFix MOVE_TO_IMPLEMENTS_LIST = new ExtendsImplementsFix(false); - - private final boolean moveToExtendsList; - - private ExtendsImplementsFix(boolean moveToExtendsList) { - this.moveToExtendsList = moveToExtendsList; - } - - @NotNull - @Override - public String getText() { - return getFamilyName(); - } - - @NotNull - @Override - public String getFamilyName() { - return GroovyBundle.message(moveToExtendsList ? "move.to.extends.list" : "move.to.implements.list"); - } - - @Override - public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - return file.findReferenceAt(editor.getCaretModel().getOffset()) != null; - } - - @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - final PsiReference ref = file.findReferenceAt(editor.getCaretModel().getOffset()); - - PsiElement element = ref.getElement(); - while (element.getParent() instanceof GrCodeReferenceElement) element = element.getParent(); - final GrReferenceList oldRefList = ((GrReferenceList)element.getParent()); - final GrTypeDefinition classParent = ((GrTypeDefinition)oldRefList.getParent()); - GrReferenceList refList = moveToExtendsList ? classParent.getExtendsClause() : classParent.getImplementsClause(); - if (refList == null) { - final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project); - if (moveToExtendsList) { - refList = factory.createExtendsClause(); - refList = (GrReferenceList)classParent.addAfter(refList, classParent.getNameIdentifierGroovy()); - } - else { - refList = factory.createImplementsClause(); - refList = (GrReferenceList)classParent.addAfter(refList, classParent.getExtendsClause()); - } - } - refList.add(element.copy()); - - if (oldRefList.getReferenceElements().length==1) { - oldRefList.delete(); - } - else { - final PsiElement prev = PsiUtil.skipWhitespacesAndComments(element.getPrevSibling(), false); - if (prev != null && prev.getNode().getElementType().equals(GroovyTokenTypes.mCOMMA)) { - prev.delete(); - } - else { - final PsiElement next = PsiUtil.skipWhitespacesAndComments(element.getNextSibling(), false); - if (next != null && next.getNode().getElementType().equals(GroovyTokenTypes.mCOMMA)) { - next.delete(); - } - } - element.delete(); - } - } - - @Override - public boolean startInWriteAction() { - return true; - } -} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/implExtQuickFix/ImplementsExtendsQuickFixTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/implExtQuickFix/ImplementsExtendsQuickFixTest.groovy new file mode 100644 index 000000000000..c1f689b406aa --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/implExtQuickFix/ImplementsExtendsQuickFixTest.groovy @@ -0,0 +1,53 @@ +package org.jetbrains.plugins.groovy.refactoring.implExtQuickFix + +import com.intellij.openapi.application.ApplicationManager +import com.intellij.psi.PsiFile +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.plugins.groovy.annotator.intentions.ChangeExtendsImplementsQuickFix +import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase +import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition +import org.jetbrains.plugins.groovy.util.TestUtils +/** + * User: Dmitry.Krasilschikov + * Date: 11.10.2007 + */ +public class ImplementsExtendsQuickFixTest extends LightCodeInsightFixtureTestCase { + + final String basePath = TestUtils.testDataPath + "groovy/extendsImplementsFix/" + + public void testClass1() { doTest() } + public void testExt1() { doTest() } + public void testImpl1() { doTest() } + public void testImpl2() { doTest() } + public void testImplext1() { doTest() } + public void testImplExt2() { doTest() } + public void testInterface1() { doTest() } + + + + public void doTest() { + final List data = TestUtils.readInput(testDataPath + getTestName(true) + ".test") + String fileText = data.get(0) + final PsiFile psiFile = TestUtils.createPseudoPhysicalGroovyFile(project, fileText) + assert psiFile instanceof GroovyFileBase + final GrTypeDefinition[] typeDefinitions = ((GroovyFileBase)psiFile).typeDefinitions + final GrTypeDefinition typeDefinition = typeDefinitions[typeDefinitions.length - 1] + String newText + if (typeDefinition.implementsClause == null && typeDefinition.extendsClause == null) { + newText = "" + } + else { + + ApplicationManager.application.runWriteAction { + ChangeExtendsImplementsQuickFix fix = new ChangeExtendsImplementsQuickFix(typeDefinition) + fix.invoke(project, null, psiFile) + doPostponedFormatting(project) + } as Runnable + + final GrTypeDefinition[] newTypeDefinitions = ((GroovyFileBase)psiFile).typeDefinitions + newText = newTypeDefinitions[newTypeDefinitions.length - 1].text + } + assertEquals(data.get(1), newText) + } + +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/implExtQuickFix/ImplementsExtendsQuickFixTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/implExtQuickFix/ImplementsExtendsQuickFixTest.java deleted file mode 100644 index da2c630d6327..000000000000 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/implExtQuickFix/ImplementsExtendsQuickFixTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.jetbrains.plugins.groovy.refactoring.implExtQuickFix; - -import com.intellij.openapi.application.Result; -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.psi.PsiFile; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; -import org.jetbrains.plugins.groovy.annotator.intentions.ChangeExtendsImplementsQuickFix; -import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; -import org.jetbrains.plugins.groovy.util.TestUtils; - -import java.util.List; - -/** - * User: Dmitry.Krasilschikov - * Date: 11.10.2007 - */ -public class ImplementsExtendsQuickFixTest extends LightCodeInsightFixtureTestCase { - - @Override - protected String getBasePath() { - return TestUtils.getTestDataPath() + "groovy/extendsImplementsFix/"; - } - - public void testClass1() throws Throwable { doTest(); } - public void testExt1() throws Throwable { doTest(); } - public void testImpl1() throws Throwable { doTest(); } - public void testImpl2() throws Throwable { doTest(); } - public void testImplext1() throws Throwable { doTest(); } - public void testImplExt2() throws Throwable { doTest(); } - public void testInterface1() throws Throwable { doTest(); } - - - - public void doTest() throws Exception { - final List data = TestUtils.readInput(getTestDataPath() + getTestName(true) + ".test"); - String fileText = data.get(0); - final PsiFile psiFile = TestUtils.createPseudoPhysicalGroovyFile(getProject(), fileText); - assert psiFile instanceof GroovyFileBase; - final GrTypeDefinition[] typeDefinitions = ((GroovyFileBase) psiFile).getTypeDefinitions(); - final GrTypeDefinition typeDefinition = typeDefinitions[typeDefinitions.length - 1]; - String newText; - if (typeDefinition.getImplementsClause() == null && typeDefinition.getExtendsClause() == null) { - newText = ""; - } else { - new WriteCommandAction(getProject()) { - @Override - protected void run(Result result) throws Throwable { - ChangeExtendsImplementsQuickFix fix = - new ChangeExtendsImplementsQuickFix(typeDefinition.getExtendsClause(), typeDefinition.getImplementsClause()); - fix.invoke(getProject(), null, psiFile); - } - }.execute(); - - final GrTypeDefinition[] newTypeDefinitions = ((GroovyFileBase) psiFile).getTypeDefinitions(); - newText = newTypeDefinitions[newTypeDefinitions.length - 1].getText(); - } - assertEquals(data.get(1), newText); - } - -} diff --git a/plugins/groovy/testdata/groovy/extendsImplementsFix/implExt2.test b/plugins/groovy/testdata/groovy/extendsImplementsFix/implExt2.test index 488fdb3d2202..2cae47ea5a03 100644 --- a/plugins/groovy/testdata/groovy/extendsImplementsFix/implExt2.test +++ b/plugins/groovy/testdata/groovy/extendsImplementsFix/implExt2.test @@ -1,5 +1,3 @@ -interface Runnable { -} class B { } class A extends Runnable implements B { diff --git a/plugins/groovy/testdata/groovy/extendsImplementsFix/interface1.test b/plugins/groovy/testdata/groovy/extendsImplementsFix/interface1.test index 9d2823dc18db..2acc64c6a5e3 100644 --- a/plugins/groovy/testdata/groovy/extendsImplementsFix/interface1.test +++ b/plugins/groovy/testdata/groovy/extendsImplementsFix/interface1.test @@ -4,5 +4,5 @@ interface C {} interface D extends A implements B, C { } ----- -interface D extends C { +interface D extends C, A, B { } \ No newline at end of file