diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index d4c30962b2f..97c4d158a39 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -49,6 +49,7 @@ import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixMultiFileTest; import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixTest; import org.jetbrains.jet.psi.AbstractJetPsiMatcherTest; import org.jetbrains.jet.resolve.AbstractResolveTest; +import org.jetbrains.jet.safeDelete.AbstractJetSafeDeleteTest; import org.jetbrains.jet.test.generator.SimpleTestClassModel; import org.jetbrains.jet.test.generator.TestClassModel; import org.jetbrains.jet.test.generator.TestGenerator; @@ -395,6 +396,14 @@ public class GenerateTests { AbstractJetQuickDocProviderTest.class, testModel("idea/testData/editor/quickDoc", "doTest") ); + + generateTest( + "idea/tests/", + "JetSafeDeleteTestGenerated", + AbstractJetSafeDeleteTest.class, + testModel("idea/testData/safeDelete/deleteClass", "doClassTest"), + testModel("idea/testData/safeDelete/deleteObject", "doObjectTest") + ); } private static SimpleTestClassModel testModel(@NotNull String rootPath) { diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 206ae2c5e69..ad170be5a14 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -227,6 +227,7 @@ + diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringSupportProvider.java b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringSupportProvider.java index f6f40234e87..b814bc4086a 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringSupportProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringSupportProvider.java @@ -21,16 +21,21 @@ import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.changeSignature.ChangeSignatureHandler; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.psi.JetFunction; -import org.jetbrains.jet.lang.psi.JetProperty; +import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureHandler; import org.jetbrains.jet.plugin.refactoring.introduceVariable.JetIntroduceVariableHandler; +import org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinSafeDeleteProcessor; /** * User: Alefas * Date: 25.01.12 */ public class JetRefactoringSupportProvider extends RefactoringSupportProvider { + @Override + public boolean isSafeDeleteAvailable(PsiElement element) { + return KotlinSafeDeleteProcessor.checkElement(element); + } + @Override public RefactoringActionHandler getIntroduceVariableHandler() { return new JetIntroduceVariableHandler(); diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java new file mode 100644 index 00000000000..1921af9663f --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java @@ -0,0 +1,125 @@ +/* + * Copyright 2010-2013 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.jet.plugin.refactoring.safeDelete; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiReference; +import com.intellij.psi.search.searches.ReferencesSearch; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor; +import com.intellij.refactoring.safeDelete.NonCodeUsageSearchInfo; +import com.intellij.refactoring.safeDelete.SafeDeleteProcessor; +import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo; +import com.intellij.usageView.UsageInfo; +import com.intellij.util.Processor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.psi.JetImportDirective; +import org.jetbrains.jet.lang.psi.JetObjectDeclaration; +import org.jetbrains.jet.lang.psi.JetObjectDeclarationName; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor { + public static boolean checkElement(PsiElement element) { + return element instanceof JetClassOrObject + || element instanceof JetObjectDeclarationName; + } + + @Override + public boolean handlesElement(PsiElement element) { + return checkElement(element); + } + + protected static NonCodeUsageSearchInfo getDefaultNonCodeUsageSearchInfo( + @NotNull PsiElement element, @NotNull PsiElement[] allElementsToDelete + ) { + return new NonCodeUsageSearchInfo(SafeDeleteProcessor.getDefaultInsideDeletedCondition(allElementsToDelete), element); + } + + @Nullable + @Override + public NonCodeUsageSearchInfo findUsages(PsiElement element, PsiElement[] allElementsToDelete, List result) { + if (element instanceof JetClassOrObject) { + return findClassOrObjectUsages(element, (JetClassOrObject) element, allElementsToDelete, result); + } + if (element instanceof JetObjectDeclarationName && element.getParent() instanceof JetObjectDeclaration) { + return findClassOrObjectUsages(element, (JetObjectDeclaration) element.getParent(), allElementsToDelete, result); + } + return getDefaultNonCodeUsageSearchInfo(element, allElementsToDelete); + } + + @SuppressWarnings("MethodOverridesPrivateMethodOfSuperclass") + protected static boolean isInside(PsiElement place, PsiElement[] ancestors) { + return isInside(place, Arrays.asList(ancestors)); + } + + @SuppressWarnings("MethodOverridesPrivateMethodOfSuperclass") + protected static boolean isInside(PsiElement place, Collection ancestors) { + for (PsiElement element : ancestors) { + if (isInside(place, element)) return true; + } + return false; + } + + protected static NonCodeUsageSearchInfo findClassOrObjectUsages( + PsiElement referencedElement, + final JetClassOrObject classOrObject, + final PsiElement[] allElementsToDelete, + final List result + ) { + ReferencesSearch.search(referencedElement).forEach(new Processor() { + @Override + public boolean process(PsiReference reference) { + PsiElement element = reference.getElement(); + + if (!isInside(element, allElementsToDelete)) { + JetImportDirective importDirective = PsiTreeUtil.getParentOfType(element, JetImportDirective.class, false); + if (importDirective != null) { + result.add(new SafeDeleteImportDirectiveUsageInfo(importDirective, classOrObject)); + return true; + } + + result.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, classOrObject, false)); + } + return true; + } + }); + + return getDefaultNonCodeUsageSearchInfo(referencedElement, allElementsToDelete); + } + + @Nullable + @Override + public UsageInfo[] preprocessUsages(Project project, UsageInfo[] usages) { + return usages; + } + + @Override + public Collection getAdditionalElementsToDelete( + PsiElement element, Collection allElementsToDelete, boolean askUser + ) { + if (element instanceof JetObjectDeclarationName && element.getParent() instanceof JetObjectDeclaration) { + return Arrays.asList(element.getParent()); + } + return super.getAdditionalElementsToDelete(element, allElementsToDelete, askUser); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/SafeDeleteImportDirectiveUsageInfo.java b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/SafeDeleteImportDirectiveUsageInfo.java new file mode 100644 index 00000000000..05e99fcb973 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/SafeDeleteImportDirectiveUsageInfo.java @@ -0,0 +1,57 @@ +/* + * Copyright 2010-2013 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.jet.plugin.refactoring.safeDelete; + +import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; + +public class SafeDeleteImportDirectiveUsageInfo extends SafeDeleteReferenceSimpleDeleteUsageInfo { + public SafeDeleteImportDirectiveUsageInfo(@NotNull JetImportDirective importDirective, @NotNull JetDeclaration declaration) { + super(importDirective, declaration, isSafeToDelete(declaration, importDirective)); + } + + private static boolean isSafeToDelete(@NotNull JetDeclaration declaration, @NotNull JetImportDirective importDirective) { + JetExpression importExpr = importDirective.getImportedReference(); + + JetReferenceExpression importReference = null; + if (importExpr instanceof JetSimpleNameExpression) { + importReference = (JetReferenceExpression) importExpr; + } + else if (importExpr instanceof JetDotQualifiedExpression) { + JetExpression selector = ((JetDotQualifiedExpression) importExpr).getSelectorExpression(); + if (selector instanceof JetSimpleNameExpression) { + importReference = (JetReferenceExpression) selector; + } + } + if (importReference == null) return false; + + BindingContext bindingContext = + AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) declaration.getContainingFile()).getBindingContext(); + + DeclarationDescriptor referenceDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, importReference); + + DeclarationDescriptor declarationDescriptor = declaration instanceof JetObjectDeclaration + ? bindingContext.get(BindingContext.OBJECT_DECLARATION, ((JetObjectDeclaration) declaration).getNameAsDeclaration()) + : bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration); + + return referenceDescriptor == declarationDescriptor; + } +} diff --git a/idea/testData/safeDelete/deleteClass/class1.kt b/idea/testData/safeDelete/deleteClass/class1.kt new file mode 100644 index 00000000000..e9b460bc80e --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/class1.kt @@ -0,0 +1,11 @@ +package test + +import test.A + +class A { + +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/class1.kt.after b/idea/testData/safeDelete/deleteClass/class1.kt.after new file mode 100644 index 00000000000..191deddb2f8 --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/class1.kt.after @@ -0,0 +1,5 @@ +package test + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/class2.kt b/idea/testData/safeDelete/deleteClass/class2.kt new file mode 100644 index 00000000000..a2cc01c4685 --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/class2.kt @@ -0,0 +1,11 @@ +package test + +import test.A + +class A { + +} + +class B: A { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/class2.kt.messages b/idea/testData/safeDelete/deleteClass/class2.kt.messages new file mode 100644 index 00000000000..3b47612540c --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/class2.kt.messages @@ -0,0 +1,2 @@ +Class A has 1 usage that is not safe to delete. +Of those 0 usages are in strings, comments, or non-code files. \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/nestedClass1.kt b/idea/testData/safeDelete/deleteClass/nestedClass1.kt new file mode 100644 index 00000000000..eda9980f59b --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/nestedClass1.kt @@ -0,0 +1,13 @@ +package test + +import test.A.C + +class A { + class C { + + } +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/nestedClass1.kt.after b/idea/testData/safeDelete/deleteClass/nestedClass1.kt.after new file mode 100644 index 00000000000..31084708c8c --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/nestedClass1.kt.after @@ -0,0 +1,8 @@ +package test + +class A { +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/nestedClass2.kt b/idea/testData/safeDelete/deleteClass/nestedClass2.kt new file mode 100644 index 00000000000..88f09bcdf0a --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/nestedClass2.kt @@ -0,0 +1,13 @@ +package test + +import test.A.C + +class A { + class C { + + } +} + +class B { + val x = A.C() +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/nestedClass2.kt.messages b/idea/testData/safeDelete/deleteClass/nestedClass2.kt.messages new file mode 100644 index 00000000000..de7b986cf61 --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/nestedClass2.kt.messages @@ -0,0 +1,2 @@ +Class C has 1 usage that is not safe to delete. +Of those 0 usages are in strings, comments, or non-code files. \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/noUsages.kt b/idea/testData/safeDelete/deleteClass/noUsages.kt new file mode 100644 index 00000000000..7831382b7c4 --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/noUsages.kt @@ -0,0 +1,11 @@ +class C { + +} + +class A { + +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/noUsages.kt.after b/idea/testData/safeDelete/deleteClass/noUsages.kt.after new file mode 100644 index 00000000000..2bb2a83ef25 --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/noUsages.kt.after @@ -0,0 +1,7 @@ +class C { + +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/trait1.kt b/idea/testData/safeDelete/deleteClass/trait1.kt new file mode 100644 index 00000000000..db5643b508b --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/trait1.kt @@ -0,0 +1,10 @@ +package test + +import test.A + +trait A { +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/trait1.kt.after b/idea/testData/safeDelete/deleteClass/trait1.kt.after new file mode 100644 index 00000000000..191deddb2f8 --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/trait1.kt.after @@ -0,0 +1,5 @@ +package test + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/trait2.kt b/idea/testData/safeDelete/deleteClass/trait2.kt new file mode 100644 index 00000000000..61c2c37148b --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/trait2.kt @@ -0,0 +1,11 @@ +package test + +import test.A + +trait A { + +} + +class B: A { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/trait2.kt.messages b/idea/testData/safeDelete/deleteClass/trait2.kt.messages new file mode 100644 index 00000000000..599dc5b1810 --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/trait2.kt.messages @@ -0,0 +1,2 @@ +Trait A has 1 usage that is not safe to delete. +Of those 0 usages are in strings, comments, or non-code files. \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/unsafeImport.kt b/idea/testData/safeDelete/deleteClass/unsafeImport.kt new file mode 100644 index 00000000000..b208ab6468a --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/unsafeImport.kt @@ -0,0 +1,13 @@ +package test + +import test.A.C + +class A { + class C { + + } +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteClass/unsafeImport.kt.messages b/idea/testData/safeDelete/deleteClass/unsafeImport.kt.messages new file mode 100644 index 00000000000..3b47612540c --- /dev/null +++ b/idea/testData/safeDelete/deleteClass/unsafeImport.kt.messages @@ -0,0 +1,2 @@ +Class A has 1 usage that is not safe to delete. +Of those 0 usages are in strings, comments, or non-code files. \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/nestedObject1.kt b/idea/testData/safeDelete/deleteObject/nestedObject1.kt new file mode 100644 index 00000000000..163a596ca56 --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/nestedObject1.kt @@ -0,0 +1,11 @@ +package test + +object A { + object O { + + } +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/nestedObject1.kt.after b/idea/testData/safeDelete/deleteObject/nestedObject1.kt.after new file mode 100644 index 00000000000..af2dd5b418f --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/nestedObject1.kt.after @@ -0,0 +1,8 @@ +package test + +object A { +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/nestedObject2.kt b/idea/testData/safeDelete/deleteObject/nestedObject2.kt new file mode 100644 index 00000000000..259ccd0b136 --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/nestedObject2.kt @@ -0,0 +1,13 @@ +package test + +import test.A.O + +object A { + object O { + + } +} + +class B { + val x = A.O +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/nestedObject2.kt.messages b/idea/testData/safeDelete/deleteObject/nestedObject2.kt.messages new file mode 100644 index 00000000000..aed29791f35 --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/nestedObject2.kt.messages @@ -0,0 +1,2 @@ +Object O has 1 usage that is not safe to delete. +Of those 0 usages are in strings, comments, or non-code files. \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/noUsages.kt b/idea/testData/safeDelete/deleteObject/noUsages.kt new file mode 100644 index 00000000000..aa9f22bd145 --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/noUsages.kt @@ -0,0 +1,11 @@ +class C { + +} + +object A { + +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/noUsages.kt.after b/idea/testData/safeDelete/deleteObject/noUsages.kt.after new file mode 100644 index 00000000000..2bb2a83ef25 --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/noUsages.kt.after @@ -0,0 +1,7 @@ +class C { + +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/object1.kt b/idea/testData/safeDelete/deleteObject/object1.kt new file mode 100644 index 00000000000..819a8024eb1 --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/object1.kt @@ -0,0 +1,11 @@ +package test + +import test.A + +object A { + +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/object1.kt.after b/idea/testData/safeDelete/deleteObject/object1.kt.after new file mode 100644 index 00000000000..191deddb2f8 --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/object1.kt.after @@ -0,0 +1,5 @@ +package test + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/object2.kt b/idea/testData/safeDelete/deleteObject/object2.kt new file mode 100644 index 00000000000..33a73c4c538 --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/object2.kt @@ -0,0 +1,11 @@ +package test + +import test.A + +object A { + +} + +class B { + val x = A +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/object2.kt.messages b/idea/testData/safeDelete/deleteObject/object2.kt.messages new file mode 100644 index 00000000000..464daffdd24 --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/object2.kt.messages @@ -0,0 +1,2 @@ +Object A has 1 usage that is not safe to delete. +Of those 0 usages are in strings, comments, or non-code files. \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/unsafeImport.kt b/idea/testData/safeDelete/deleteObject/unsafeImport.kt new file mode 100644 index 00000000000..e2c5ea55eec --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/unsafeImport.kt @@ -0,0 +1,11 @@ +package test + +import test.A.x + +object A { + val x = "" +} + +class B { + +} \ No newline at end of file diff --git a/idea/testData/safeDelete/deleteObject/unsafeImport.kt.messages b/idea/testData/safeDelete/deleteObject/unsafeImport.kt.messages new file mode 100644 index 00000000000..464daffdd24 --- /dev/null +++ b/idea/testData/safeDelete/deleteObject/unsafeImport.kt.messages @@ -0,0 +1,2 @@ +Object A has 1 usage that is not safe to delete. +Of those 0 usages are in strings, comments, or non-code files. \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/safeDelete/AbstractJetSafeDeleteTest.java b/idea/tests/org/jetbrains/jet/safeDelete/AbstractJetSafeDeleteTest.java new file mode 100644 index 00000000000..0473afb8389 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/safeDelete/AbstractJetSafeDeleteTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2010-2013 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.jet.safeDelete; + +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.BaseRefactoringProcessor; +import com.intellij.refactoring.safeDelete.SafeDeleteHandler; +import com.intellij.testFramework.LightCodeInsightTestCase; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetObjectDeclarationName; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public abstract class AbstractJetSafeDeleteTest extends LightCodeInsightTestCase { + public void doClassTest(@NotNull String path) throws Exception { + doTest(path, JetClass.class); + } + + public void doObjectTest(@NotNull String path) throws Exception { + doTest(path, JetObjectDeclarationName.class); + } + + private void doTest(@NotNull String path, @NotNull Class elementClass) throws Exception { + configureByFile(path); + + DataContext dataContext = getCurrentEditorDataContext(); + PsiElement element = PsiTreeUtil.getParentOfType(LangDataKeys.PSI_ELEMENT.getData(dataContext), elementClass, false); + + try { + new SafeDeleteHandler().invoke(getProject(), new PsiElement[] {element}, dataContext); + checkResultByFile(path + ".after"); + } + catch (BaseRefactoringProcessor.ConflictsInTestsException e) { + List messages = new ArrayList(e.getMessages()); + Collections.sort(messages); + + File messageFile = new File(path + ".messages"); + String expectedMessage = FileUtil.loadFile(messageFile, CharsetToolkit.UTF8, true); + assertEquals(expectedMessage, StringUtil.join(messages, "\n")); + } + } + + @NotNull + @Override + protected String getTestDataPath() { + return ""; + } +} diff --git a/idea/tests/org/jetbrains/jet/safeDelete/JetSafeDeleteTestGenerated.java b/idea/tests/org/jetbrains/jet/safeDelete/JetSafeDeleteTestGenerated.java new file mode 100644 index 00000000000..6440a519560 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/safeDelete/JetSafeDeleteTestGenerated.java @@ -0,0 +1,127 @@ +/* + * Copyright 2010-2013 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.jet.safeDelete; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.safeDelete.AbstractJetSafeDeleteTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@InnerTestClasses({JetSafeDeleteTestGenerated.DeleteClass.class, JetSafeDeleteTestGenerated.DeleteObject.class}) +public class JetSafeDeleteTestGenerated extends AbstractJetSafeDeleteTest { + @TestMetadata("idea/testData/safeDelete/deleteClass") + public static class DeleteClass extends AbstractJetSafeDeleteTest { + public void testAllFilesPresentInDeleteClass() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/safeDelete/deleteClass"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("class1.kt") + public void testClass1() throws Exception { + doClassTest("idea/testData/safeDelete/deleteClass/class1.kt"); + } + + @TestMetadata("class2.kt") + public void testClass2() throws Exception { + doClassTest("idea/testData/safeDelete/deleteClass/class2.kt"); + } + + @TestMetadata("nestedClass1.kt") + public void testNestedClass1() throws Exception { + doClassTest("idea/testData/safeDelete/deleteClass/nestedClass1.kt"); + } + + @TestMetadata("nestedClass2.kt") + public void testNestedClass2() throws Exception { + doClassTest("idea/testData/safeDelete/deleteClass/nestedClass2.kt"); + } + + @TestMetadata("noUsages.kt") + public void testNoUsages() throws Exception { + doClassTest("idea/testData/safeDelete/deleteClass/noUsages.kt"); + } + + @TestMetadata("trait1.kt") + public void testTrait1() throws Exception { + doClassTest("idea/testData/safeDelete/deleteClass/trait1.kt"); + } + + @TestMetadata("trait2.kt") + public void testTrait2() throws Exception { + doClassTest("idea/testData/safeDelete/deleteClass/trait2.kt"); + } + + @TestMetadata("unsafeImport.kt") + public void testUnsafeImport() throws Exception { + doClassTest("idea/testData/safeDelete/deleteClass/unsafeImport.kt"); + } + + } + + @TestMetadata("idea/testData/safeDelete/deleteObject") + public static class DeleteObject extends AbstractJetSafeDeleteTest { + public void testAllFilesPresentInDeleteObject() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/safeDelete/deleteObject"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("nestedObject1.kt") + public void testNestedObject1() throws Exception { + doObjectTest("idea/testData/safeDelete/deleteObject/nestedObject1.kt"); + } + + @TestMetadata("nestedObject2.kt") + public void testNestedObject2() throws Exception { + doObjectTest("idea/testData/safeDelete/deleteObject/nestedObject2.kt"); + } + + @TestMetadata("noUsages.kt") + public void testNoUsages() throws Exception { + doObjectTest("idea/testData/safeDelete/deleteObject/noUsages.kt"); + } + + @TestMetadata("object1.kt") + public void testObject1() throws Exception { + doObjectTest("idea/testData/safeDelete/deleteObject/object1.kt"); + } + + @TestMetadata("object2.kt") + public void testObject2() throws Exception { + doObjectTest("idea/testData/safeDelete/deleteObject/object2.kt"); + } + + @TestMetadata("unsafeImport.kt") + public void testUnsafeImport() throws Exception { + doObjectTest("idea/testData/safeDelete/deleteObject/unsafeImport.kt"); + } + + } + + public static Test suite() { + TestSuite suite = new TestSuite("JetSafeDeleteTestGenerated"); + suite.addTestSuite(DeleteClass.class); + suite.addTestSuite(DeleteObject.class); + return suite; + } +}