diff --git a/annotations/com/intellij/openapi/util/annotations.xml b/annotations/com/intellij/openapi/util/annotations.xml
index b11815b34e4..c04bb1a0672 100644
--- a/annotations/com/intellij/openapi/util/annotations.xml
+++ b/annotations/com/intellij/openapi/util/annotations.xml
@@ -1,4 +1,8 @@
+ -
+
+
-
diff --git a/annotations/com/intellij/psi/annotations.xml b/annotations/com/intellij/psi/annotations.xml
index 6fa70cb6668..9ebf450d9bf 100644
--- a/annotations/com/intellij/psi/annotations.xml
+++ b/annotations/com/intellij/psi/annotations.xml
@@ -11,6 +11,9 @@
-
+ -
+
+
-
diff --git a/annotations/com/intellij/psi/search/searches/annotations.xml b/annotations/com/intellij/psi/search/searches/annotations.xml
index 72806268982..9a49c51ad91 100644
--- a/annotations/com/intellij/psi/search/searches/annotations.xml
+++ b/annotations/com/intellij/psi/search/searches/annotations.xml
@@ -19,4 +19,29 @@
name='com.intellij.psi.search.searches.OverridingMethodsSearch com.intellij.util.Query<com.intellij.psi.PsiMethod> search(com.intellij.psi.PsiMethod, com.intellij.psi.search.SearchScope, boolean)'>
+ -
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
\ No newline at end of file
diff --git a/annotations/com/intellij/refactoring/safeDelete/annotations.xml b/annotations/com/intellij/refactoring/safeDelete/annotations.xml
new file mode 100644
index 00000000000..364c50d8893
--- /dev/null
+++ b/annotations/com/intellij/refactoring/safeDelete/annotations.xml
@@ -0,0 +1,98 @@
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/annotations/com/intellij/refactoring/safeDelete/usageInfo/annotations.xml b/annotations/com/intellij/refactoring/safeDelete/usageInfo/annotations.xml
new file mode 100644
index 00000000000..9a79b9c84af
--- /dev/null
+++ b/annotations/com/intellij/refactoring/safeDelete/usageInfo/annotations.xml
@@ -0,0 +1,8 @@
+
+ -
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/annotations/com/intellij/usageView/annotations.xml b/annotations/com/intellij/usageView/annotations.xml
new file mode 100644
index 00000000000..ac5915627cc
--- /dev/null
+++ b/annotations/com/intellij/usageView/annotations.xml
@@ -0,0 +1,8 @@
+
+ -
+
+
+ -
+
+
+
\ No newline at end of file
diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt
index 130056eae0e..40df221c6bc 100644
--- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt
+++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/lightClassUtils.kt
@@ -39,6 +39,9 @@ import com.intellij.psi.PsiNamedElement
import com.intellij.psi.PsiNamedElement
import org.jetbrains.jet.lang.psi.JetCallableDeclaration
import org.jetbrains.jet.lang.psi.psiUtil.isExtensionDeclaration
+import com.intellij.psi.PsiClass
+
+fun JetClassOrObject.toLightClass(): PsiClass? = LightClassUtil.getPsiClass(this)
fun JetDeclaration.toLightElements(): List =
when (this) {
diff --git a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java
index 149ed0878ef..c0152a6d21d 100644
--- a/core/descriptors/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java
+++ b/core/descriptors/src/org/jetbrains/jet/lang/descriptors/CallableMemberDescriptor.java
@@ -16,11 +16,13 @@
package org.jetbrains.jet.lang.descriptors;
+import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
public interface CallableMemberDescriptor extends CallableDescriptor, MemberDescriptor {
+ @KotlinSignature("fun getOverriddenDescriptors(): MutableSet")
@NotNull
@Override
Set extends CallableMemberDescriptor> getOverriddenDescriptors();
diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringSupportProvider.java b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringSupportProvider.java
index 735e46d3f57..ca278e52c8f 100644
--- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringSupportProvider.java
+++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringSupportProvider.java
@@ -25,12 +25,12 @@ import org.jetbrains.annotations.Nullable;
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;
+import org.jetbrains.jet.plugin.refactoring.safeDelete.SafeDeletePackage;
public class JetRefactoringSupportProvider extends RefactoringSupportProvider {
@Override
public boolean isSafeDeleteAvailable(@NotNull PsiElement element) {
- return KotlinSafeDeleteProcessor.canDeleteElement(element);
+ return SafeDeletePackage.canDeleteElement(element);
}
@Override
diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java
index 663f0ead4c5..8e3ed3becd8 100644
--- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java
+++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java
@@ -34,6 +34,7 @@ import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.ui.components.JBList;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
+import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.asJava.AsJavaPackage;
@@ -117,6 +118,8 @@ public class JetRefactoringUtil {
return markAsJava ? "[Java] " + description : description;
}
+ @KotlinSignature(
+ "fun checkSuperMethods(declaration: JetDeclaration, ignore: Collection?, actionStringKey: String): MutableList?")
@Nullable
public static List extends PsiElement> checkSuperMethods(
@NotNull JetDeclaration declaration, @Nullable Collection ignore, @NotNull String actionStringKey
@@ -287,6 +290,7 @@ public class JetRefactoringUtil {
return "class " + classOrObject.getName();
}
+ @KotlinSignature("fun checkParametersInMethodHierarchy(parameter: PsiParameter): MutableCollection?")
@Nullable
public static Collection extends PsiElement> checkParametersInMethodHierarchy(@NotNull PsiParameter parameter) {
PsiMethod method = (PsiMethod)parameter.getDeclarationScope();
diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.java b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.java
index 0f97106267e..cd61515a0a1 100644
--- a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.java
+++ b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinJavaSafeDeleteDelegate.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2010-2014 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.psi.PsiElement;
diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinOverridingDialog.java b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinOverridingDialog.java
index 382483264c0..33ac4bd6433 100644
--- a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinOverridingDialog.java
+++ b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinOverridingDialog.java
@@ -30,6 +30,7 @@ import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.table.JBTable;
import com.intellij.usageView.UsageInfo;
import com.intellij.usages.impl.UsagePreviewPanel;
+import jet.runtime.typeinfo.KotlinSignature;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
@@ -116,6 +117,7 @@ class KotlinOverridingDialog extends DialogWrapper {
return "#org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinOverridingDialog";
}
+ @KotlinSignature("fun getSelected(): ArrayList")
public ArrayList getSelected() {
ArrayList result = new ArrayList();
for (int i = 0; i < myChecked.length; i++) {
diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java
deleted file mode 100644
index 698cbe423b8..00000000000
--- a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * 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.application.ApplicationManager;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Condition;
-import com.intellij.openapi.util.Conditions;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiParameter;
-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.usageInfo.SafeDeleteOverrideAnnotation;
-import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteOverridingMethodUsageInfo;
-import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceJavaDeleteUsageInfo;
-import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo;
-import com.intellij.usageView.UsageInfo;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.Processor;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.jet.asJava.AsJavaPackage;
-import org.jetbrains.jet.asJava.LightClassUtil;
-import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
-import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
-import org.jetbrains.jet.lang.descriptors.Modality;
-import org.jetbrains.jet.lang.psi.*;
-import org.jetbrains.jet.lang.psi.psiUtil.PsiUtilPackage;
-import org.jetbrains.jet.lang.resolve.BindingContext;
-import org.jetbrains.jet.lang.resolve.java.jetAsJava.KotlinLightMethod;
-import org.jetbrains.jet.lexer.JetTokens;
-import org.jetbrains.jet.plugin.JetBundle;
-import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
-import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil;
-import org.jetbrains.jet.plugin.references.JetPsiReference;
-
-import java.util.*;
-
-public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
- public static boolean canDeleteElement(@NotNull PsiElement element) {
- if (PsiUtilPackage.isObjectLiteral(element)) return false;
- if (element instanceof JetParameter) {
- JetDeclaration declaration = PsiTreeUtil.getParentOfType(element, JetDeclaration.class);
- return declaration != null && !(declaration instanceof JetPropertyAccessor && ((JetPropertyAccessor) declaration).isSetter());
- }
- return element instanceof JetClassOrObject
- || element instanceof JetNamedFunction
- || element instanceof PsiMethod
- || element instanceof JetProperty
- || element instanceof JetTypeParameter;
- }
-
- @Override
- public boolean handlesElement(@NotNull PsiElement element) {
- return canDeleteElement(element);
- }
-
- @NotNull
- protected static NonCodeUsageSearchInfo getSearchInfo(
- @NotNull PsiElement element, @NotNull Collection extends PsiElement> ignoredElements
- ) {
-
- return new NonCodeUsageSearchInfo(getCondition(ignoredElements), element);
- }
-
- private static Condition getCondition(final Collection extends PsiElement> ignoredElements) {
- return new Condition() {
- @Override
- public boolean value(PsiElement usage) {
- if (usage instanceof JetFile) return false;
- return isInside(usage, ignoredElements);
- }
- };
- }
-
- @NotNull
- protected static NonCodeUsageSearchInfo getSearchInfo(@NotNull PsiElement element, @NotNull PsiElement[] ignoredElements) {
- return getSearchInfo(element, Arrays.asList(ignoredElements));
- }
-
- @Nullable
- @Override
- public NonCodeUsageSearchInfo findUsages(
- @NotNull PsiElement element, @NotNull PsiElement[] allElementsToDelete, @NotNull List result
- ) {
- if (element instanceof JetClassOrObject) {
- return delegateToJavaProcessor(LightClassUtil.getPsiClass((JetClassOrObject) element), allElementsToDelete, result);
- }
- if (element instanceof JetNamedFunction) {
- JetNamedFunction function = (JetNamedFunction) element;
- if (function.isLocal()) {
- return findKotlinDeclarationUsages(function, allElementsToDelete, result);
- }
- PsiMethod method = LightClassUtil.getLightClassMethod((JetNamedFunction) element);
- if (method != null) return delegateToJavaProcessor(method, allElementsToDelete, result);
-
- return getSearchInfo(element, allElementsToDelete);
- }
- if (element instanceof PsiMethod) {
- return delegateToJavaProcessor(element, allElementsToDelete, result);
- }
- if (element instanceof JetProperty) {
- JetProperty property = (JetProperty) element;
-
- if (property.isLocal()) return findKotlinDeclarationUsages(property, allElementsToDelete, result);
- return delegateToJavaProcessor(property, allElementsToDelete, result);
- }
- if (element instanceof JetTypeParameter) {
- JetTypeParameter typeParameter = (JetTypeParameter) element;
-
- findTypeParameterUsages(typeParameter, result);
- return delegateToJavaProcessor(typeParameter, allElementsToDelete, result);
- }
- if (element instanceof JetParameter) {
- return delegateToJavaProcessor((JetParameter) element, allElementsToDelete, result);
- }
-
- return getSearchInfo(element, allElementsToDelete);
- }
-
- private NonCodeUsageSearchInfo delegateToJavaProcessor(
- JetDeclaration jetDeclaration,
- PsiElement[] allElementsToDelete,
- List result
- ) {
- return new NonCodeUsageSearchInfo(
- delegateToJavaProcessorAndCombineConditions(
- AsJavaPackage.toLightElements(jetDeclaration),
- getCondition(Arrays.asList(allElementsToDelete)),
- allElementsToDelete,
- result
- ),
- jetDeclaration
- );
- }
-
- private Condition delegateToJavaProcessorAndCombineConditions(
- Iterable extends PsiElement> elements,
- Condition insideDeleted,
- PsiElement[] allElementsToDelete,
- List result
- ) {
- for (PsiElement element: elements) {
- NonCodeUsageSearchInfo accessorSearchInfo = delegateToJavaProcessor(element, allElementsToDelete, result);
- if (accessorSearchInfo == null) continue;
-
- insideDeleted = Conditions.or(insideDeleted, accessorSearchInfo.getInsideDeletedCondition());
- }
- return insideDeleted;
- }
-
- @SuppressWarnings("MethodOverridesPrivateMethodOfSuperclass")
- protected static boolean isInside(@NotNull PsiElement place, @NotNull PsiElement[] ancestors) {
- return isInside(place, Arrays.asList(ancestors));
- }
-
- @SuppressWarnings("MethodOverridesPrivateMethodOfSuperclass")
- protected static boolean isInside(@NotNull PsiElement place, @NotNull Collection extends PsiElement> ancestors) {
- for (PsiElement element : ancestors) {
- if (isInside(place, element)) return true;
- }
- return false;
- }
-
- @SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
- public static boolean isInside(@NotNull PsiElement place, @NotNull PsiElement ancestor) {
- return JavaSafeDeleteProcessor.isInside(place, AsJavaPackage.getUnwrapped(ancestor));
- }
-
- @Nullable
- protected NonCodeUsageSearchInfo delegateToJavaProcessor(
- @Nullable PsiElement element,
- @NotNull PsiElement[] allElementsToDelete,
- @NotNull List result
- ) {
- if (element == null) return null;
-
- List javaUsages = new ArrayList();
- NonCodeUsageSearchInfo searchInfo = super.findUsages(element, allElementsToDelete, javaUsages);
-
- for (UsageInfo usageInfo : javaUsages) {
- if (usageInfo instanceof SafeDeleteOverridingMethodUsageInfo) {
- SafeDeleteOverridingMethodUsageInfo overrideUsageInfo = (SafeDeleteOverridingMethodUsageInfo) usageInfo;
-
- PsiElement usageElement = overrideUsageInfo.getSmartPointer().getElement();
- usageInfo = (usageElement != null)
- ? new KotlinSafeDeleteOverridingUsageInfo(usageElement, overrideUsageInfo.getReferencedElement())
- : null;
- }
- else if (usageInfo instanceof SafeDeleteOverrideAnnotation) {
- SafeDeleteOverrideAnnotation overrideAnnotationUsageInfo = (SafeDeleteOverrideAnnotation) usageInfo;
-
- PsiElement targetElement = overrideAnnotationUsageInfo.getSmartPointer().getElement();
- if (targetElement != null) {
- boolean noSuperMethods = ContainerUtil.and(
- AsJavaPackage.toLightMethods(targetElement),
- new Condition() {
- @Override
- public boolean value(PsiMethod method) {
- return method.findSuperMethods().length == 0;
- }
- }
- );
-
- usageInfo = noSuperMethods
- ? new KotlinSafeDeleteOverrideAnnotation(targetElement, overrideAnnotationUsageInfo.getReferencedElement())
- : null;
- }
- else {
- usageInfo = null;
- }
- }
- else if (usageInfo instanceof SafeDeleteReferenceJavaDeleteUsageInfo) {
- SafeDeleteReferenceJavaDeleteUsageInfo javaDeleteUsageInfo = (SafeDeleteReferenceJavaDeleteUsageInfo) usageInfo;
- PsiElement usageElement = javaDeleteUsageInfo.getElement();
- JetImportDirective importDirective = PsiTreeUtil.getParentOfType(usageElement, JetImportDirective.class, false);
- if (importDirective != null) {
- usageInfo = new SafeDeleteImportDirectiveUsageInfo(
- importDirective, (JetDeclaration) AsJavaPackage.getUnwrapped(element)
- );
- }
- }
- if (usageInfo != null) {
- result.add(usageInfo);
- }
- }
-
- return searchInfo;
- }
-
- @NotNull
- protected static NonCodeUsageSearchInfo findKotlinDeclarationUsages(
- @NotNull final JetDeclaration declaration,
- @NotNull final PsiElement[] allElementsToDelete,
- @NotNull final List result
- ) {
- ReferencesSearch.search(declaration, declaration.getUseScope()).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, declaration));
- }
- else {
- result.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, declaration, false));
- }
- }
- return true;
- }
- });
-
- return getSearchInfo(declaration, allElementsToDelete);
- }
-
- protected static void findTypeParameterUsages(
- @NotNull final JetTypeParameter parameter,
- @NotNull final List result
- ) {
- JetTypeParameterListOwner owner = PsiTreeUtil.getParentOfType(parameter, JetTypeParameterListOwner.class);
- if (owner == null) return;
-
- List parameterList = owner.getTypeParameters();
- final int parameterIndex = parameterList.indexOf(parameter);
-
- ReferencesSearch.search(owner).forEach(
- new Processor() {
- @Override
- public boolean process(PsiReference reference) {
- if (reference instanceof JetPsiReference) {
- processKotlinTypeArgumentListCandidate(reference, parameterIndex, result, parameter);
- }
- return true;
- }
- }
- );
- }
-
- private static void processKotlinTypeArgumentListCandidate(
- @NotNull PsiReference reference,
- int parameterIndex,
- @NotNull List result,
- @NotNull JetTypeParameter parameter
- ) {
- PsiElement referencedElement = reference.getElement();
-
- JetTypeArgumentList argList = null;
-
- JetUserType type = PsiTreeUtil.getParentOfType(referencedElement, JetUserType.class);
- if (type != null) {
- argList = type.getTypeArgumentList();
- }
- else {
- JetCallExpression callExpression = PsiTreeUtil.getParentOfType(referencedElement, JetCallExpression.class);
- if (callExpression != null) {
- argList = callExpression.getTypeArgumentList();
- }
- }
-
- if (argList != null) {
- List projections = argList.getArguments();
- if (parameterIndex < projections.size()) {
- result.add(new SafeDeleteTypeArgumentListUsageInfo(projections.get(parameterIndex), parameter));
- }
- }
- }
-
- @Override
- @Nullable
- public Collection findConflicts(@NotNull PsiElement element, @NotNull PsiElement[] allElementsToDelete) {
- if (element instanceof JetNamedFunction || element instanceof JetProperty) {
- JetClass jetClass = PsiTreeUtil.getParentOfType(element, JetClass.class);
- if (jetClass == null || jetClass.getBody() != element.getParent()) return null;
-
- JetModifierList modifierList = jetClass.getModifierList();
- if (modifierList != null && modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD)) return null;
-
- BindingContext bindingContext =
- AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext();
-
- DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
- if (!(declarationDescriptor instanceof CallableMemberDescriptor)) return null;
-
- List messages = new ArrayList();
- CallableMemberDescriptor callableDescriptor = (CallableMemberDescriptor) declarationDescriptor;
- for (CallableMemberDescriptor overridenDescriptor : callableDescriptor.getOverriddenDescriptors()) {
- if (overridenDescriptor.getModality() == Modality.ABSTRACT) {
- String message = JetBundle.message(
- "x.implements.y",
- JetRefactoringUtil.formatFunction(callableDescriptor, bindingContext, true),
- JetRefactoringUtil.formatClass(callableDescriptor.getContainingDeclaration(), bindingContext, true),
- JetRefactoringUtil.formatFunction(overridenDescriptor, bindingContext, true),
- JetRefactoringUtil.formatClass(overridenDescriptor.getContainingDeclaration(), bindingContext, true)
- );
- messages.add(message);
- }
- }
-
- if (!messages.isEmpty()) return messages;
- }
- return super.findConflicts(element, allElementsToDelete);
- }
-
- /*
- * Mostly copied from JavaSafeDeleteProcessor.preprocessUsages
- * Revision: d4fc033
- * (replaced original dialog)
- */
- @Nullable
- @Override
- public UsageInfo[] preprocessUsages(@NotNull Project project, @NotNull UsageInfo[] usages) {
- ArrayList result = new ArrayList();
- ArrayList overridingMethodUsages = new ArrayList();
-
- for (UsageInfo usage : usages) {
- if (usage instanceof KotlinSafeDeleteOverridingUsageInfo) {
- overridingMethodUsages.add(usage);
- }
- else {
- result.add(usage);
- }
- }
-
- if (!overridingMethodUsages.isEmpty()) {
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- result.addAll(overridingMethodUsages);
- }
- else {
- KotlinOverridingDialog dialog = new KotlinOverridingDialog(project, overridingMethodUsages);
- dialog.show();
- if (!dialog.isOK()) return null;
- result.addAll(dialog.getSelected());
- }
- }
-
- return result.toArray(new UsageInfo[result.size()]);
- }
-
- @Override
- public void prepareForDeletion(@NotNull PsiElement element) throws IncorrectOperationException {
- if (element instanceof PsiMethod) {
- SafeDeletePackage.cleanUpOverrides((PsiMethod) element);
- }
- else if (element instanceof JetNamedFunction) {
- PsiMethod lightMethod = LightClassUtil.getLightClassMethod((JetNamedFunction) element);
- if (lightMethod == null) {
- return;
- }
-
- SafeDeletePackage.cleanUpOverrides(lightMethod);
- }
- else if (element instanceof JetProperty) {
- LightClassUtil.PropertyAccessorsPsiMethods propertyMethods =
- LightClassUtil.getLightClassPropertyMethods((JetProperty) element);
- PsiMethod getter = propertyMethods.getGetter();
- PsiMethod setter = propertyMethods.getSetter();
-
- if (getter != null) {
- SafeDeletePackage.cleanUpOverrides(getter);
- }
- if (setter != null) {
- SafeDeletePackage.cleanUpOverrides(setter);
- }
- }
- else if (element instanceof JetTypeParameter) {
- PsiUtilPackage.deleteElementAndCleanParent(element);
- }
- else if (element instanceof JetParameter) {
- JetPsiUtil.deleteElementWithDelimiters(element);
- }
- }
-
- @Nullable
- @Override
- public Collection extends PsiElement> getElementsToSearch(
- @NotNull PsiElement element, @Nullable Module module, @NotNull Collection allElementsToDelete
- ) {
- if (element instanceof JetParameter) {
- PsiParameter psiParameter = AsJavaPackage.toPsiParameter((JetParameter) element);
- if (psiParameter != null) return JetRefactoringUtil.checkParametersInMethodHierarchy(psiParameter);
- }
-
- if (element instanceof PsiParameter) {
- return JetRefactoringUtil.checkParametersInMethodHierarchy((PsiParameter) element);
- }
-
- if (ApplicationManager.getApplication().isUnitTestMode()) {
- return Collections.singletonList(element);
- }
-
- if (element instanceof JetNamedFunction || element instanceof JetProperty) {
- return JetRefactoringUtil.checkSuperMethods(
- (JetDeclaration) element, allElementsToDelete, "super.methods.delete.with.usage.search"
- );
- }
-
- return super.getElementsToSearch(element, module, allElementsToDelete);
- }
-}
diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt
new file mode 100644
index 00000000000..a82689fda38
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2010-2014 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.application.ApplicationManager
+import com.intellij.openapi.module.Module
+import com.intellij.openapi.project.Project
+import com.intellij.openapi.util.Condition
+import com.intellij.openapi.util.Conditions
+import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.PsiParameter
+import com.intellij.psi.search.searches.ReferencesSearch
+import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor
+import com.intellij.refactoring.safeDelete.NonCodeUsageSearchInfo
+import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteOverrideAnnotation
+import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteOverridingMethodUsageInfo
+import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceJavaDeleteUsageInfo
+import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo
+import com.intellij.usageView.UsageInfo
+import org.jetbrains.jet.asJava.*
+import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor
+import org.jetbrains.jet.lang.descriptors.Modality
+import org.jetbrains.jet.lang.psi.*
+import org.jetbrains.jet.lang.resolve.BindingContext
+import org.jetbrains.jet.lexer.JetTokens
+import org.jetbrains.jet.plugin.JetBundle
+import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
+import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil
+import org.jetbrains.jet.plugin.references.JetPsiReference
+import java.util.*
+import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
+import org.jetbrains.jet.lang.psi.psiUtil.deleteElementAndCleanParent
+
+public class KotlinSafeDeleteProcessor : JavaSafeDeleteProcessor() {
+ override fun handlesElement(element: PsiElement): Boolean = element.canDeleteElement()
+
+ override fun findUsages(
+ element: PsiElement, allElementsToDelete: Array, usages: MutableList
+ ): NonCodeUsageSearchInfo {
+ val deleteList = allElementsToDelete.toList()
+
+ fun getIgnoranceCondition(): Condition {
+ return object : Condition {
+ override fun value(t: PsiElement?): Boolean {
+ if (t is JetFile) return false
+ return deleteList.any { element -> JavaSafeDeleteProcessor.isInside(t, element.unwrapped) }
+ }
+ }
+ }
+
+ fun getSearchInfo(element: PsiElement): NonCodeUsageSearchInfo {
+ return NonCodeUsageSearchInfo(getIgnoranceCondition(), element)
+ }
+
+ fun findUsagesByJavaProcessor(element: PsiElement): NonCodeUsageSearchInfo? {
+ val javaUsages = ArrayList()
+ val searchInfo = super.findUsages(element, allElementsToDelete, javaUsages)
+
+ javaUsages.map { usageInfo ->
+ when (usageInfo) {
+ is SafeDeleteOverridingMethodUsageInfo ->
+ usageInfo.getSmartPointer().getElement()?.let { usageElement ->
+ KotlinSafeDeleteOverridingUsageInfo(usageElement, usageInfo.getReferencedElement())
+ }
+
+ is SafeDeleteOverrideAnnotation ->
+ usageInfo.getSmartPointer().getElement()?.let { usageElement ->
+ if (usageElement.toLightMethods().all { method -> method.findSuperMethods().size == 0 }) {
+ KotlinSafeDeleteOverrideAnnotation(usageElement, usageInfo.getReferencedElement())
+ }
+ else null
+ }
+
+ is SafeDeleteReferenceJavaDeleteUsageInfo ->
+ usageInfo.getElement()?.let { usageElement ->
+ if (usageElement.getParentByType(javaClass()) != null) null
+ else {
+ usageElement.getParentByType(javaClass())?.let { importDirective ->
+ SafeDeleteImportDirectiveUsageInfo(importDirective, element.unwrapped as JetDeclaration)
+ } ?: usageInfo
+ }
+ }
+
+ else -> usageInfo
+ }
+ }.filterNotNull().toCollection(usages)
+
+ return searchInfo
+ }
+
+ fun findUsagesByJavaProcessor(elements: Iterator, insideDeleted: Condition): Condition =
+ elements
+ .map { element -> findUsagesByJavaProcessor(element)?.getInsideDeletedCondition() }
+ .filterNotNull()
+ .fold(insideDeleted) {(condition1, condition2) -> Conditions.or(condition1, condition2) }
+
+ fun findUsagesByJavaProcessor(jetDeclaration: JetDeclaration): NonCodeUsageSearchInfo {
+ return NonCodeUsageSearchInfo(
+ findUsagesByJavaProcessor(
+ jetDeclaration.toLightElements().iterator(),
+ getIgnoranceCondition()
+ ),
+ jetDeclaration
+ )
+ }
+
+ fun findKotlinDeclarationUsages(declaration: JetDeclaration): NonCodeUsageSearchInfo {
+ ReferencesSearch.search(declaration, declaration.getUseScope())
+ .iterator()
+ .filterNot { reference -> getIgnoranceCondition().value(reference.getElement()) }
+ .mapTo(usages) { reference ->
+ reference.getElement().getParentByType(javaClass())?.let { importDirective ->
+ SafeDeleteImportDirectiveUsageInfo(importDirective, element.unwrapped as JetDeclaration)
+ } ?: SafeDeleteReferenceSimpleDeleteUsageInfo(element, declaration, false)
+ }
+
+ return getSearchInfo(declaration)
+ }
+
+ fun findTypeParameterUsages(parameter: JetTypeParameter) {
+ val owner = parameter.getParentByType(javaClass())
+ if (owner == null) return
+
+ val parameterList = owner.getTypeParameters()
+ val parameterIndex = parameterList.indexOf(parameter)
+
+ for (reference in ReferencesSearch.search(owner)) {
+ if (reference !is JetPsiReference) continue
+
+ val referencedElement = reference.getElement()
+
+ val argList = referencedElement.getParentByType(javaClass())?.let { jetType ->
+ jetType.getTypeArgumentList()
+ } ?: referencedElement.getParentByType(javaClass())?.let { callExpression ->
+ callExpression.getTypeArgumentList()
+ } ?: null
+
+ if (argList != null) {
+ val projections = argList.getArguments()
+ if (parameterIndex < projections.size()) {
+ usages.add(SafeDeleteTypeArgumentListUsageInfo(projections.get(parameterIndex), parameter))
+ }
+ }
+ }
+ }
+
+ val searchInfo = when (element) {
+ is JetClassOrObject ->
+ element.toLightClass()?.let { klass -> findUsagesByJavaProcessor(klass) }
+
+ is JetNamedFunction -> {
+ if (element.isLocal()) {
+ findKotlinDeclarationUsages(element)
+ }
+ else {
+ element.getRepresentativeLightMethod()?.let { method -> findUsagesByJavaProcessor(method) }
+ }
+ }
+
+ is PsiMethod ->
+ findUsagesByJavaProcessor(element)
+
+ is JetProperty -> {
+ if (element.isLocal()) {
+ findKotlinDeclarationUsages(element)
+ }
+ else {
+ findUsagesByJavaProcessor(element)
+ }
+ }
+
+ is JetTypeParameter -> {
+ findTypeParameterUsages(element)
+ findUsagesByJavaProcessor(element)
+ }
+
+ is JetParameter ->
+ findUsagesByJavaProcessor(element)
+
+ else -> null
+ }
+
+ return if (searchInfo != null) searchInfo else getSearchInfo(element)
+ }
+
+ override fun findConflicts(element: PsiElement, allElementsToDelete: Array): MutableCollection? {
+ if (element is JetNamedFunction || element is JetProperty) {
+ val jetClass = element.getParentByType(javaClass())
+ if (jetClass == null || jetClass.getBody() != element.getParent()) return null
+
+ val modifierList = jetClass.getModifierList()
+ if (modifierList != null && modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD)) return null
+
+ val bindingContext = AnalyzerFacadeWithCache.getContextForElement(element as JetElement)
+
+ val declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element)
+ if (declarationDescriptor !is CallableMemberDescriptor) return null
+
+ return declarationDescriptor.getOverriddenDescriptors()
+ .iterator()
+ .filter { overridenDescriptor -> overridenDescriptor.getModality() == Modality.ABSTRACT }
+ .mapTo(ArrayList()) { overridenDescriptor ->
+ JetBundle.message(
+ "x.implements.y",
+ JetRefactoringUtil.formatFunction(declarationDescriptor, bindingContext, true),
+ JetRefactoringUtil.formatClass(declarationDescriptor.getContainingDeclaration(), bindingContext, true),
+ JetRefactoringUtil.formatFunction(overridenDescriptor, bindingContext, true),
+ JetRefactoringUtil.formatClass(overridenDescriptor.getContainingDeclaration(), bindingContext, true)
+ )
+ }
+ }
+
+ return super.findConflicts(element, allElementsToDelete)
+ }
+
+ /*
+ * Mostly copied from JavaSafeDeleteProcessor.preprocessUsages
+ * Revision: d4fc033
+ * (replaced original dialog)
+ */
+ override fun preprocessUsages(project: Project, usages: Array): Array? {
+ val result = ArrayList()
+ val overridingMethodUsages = ArrayList()
+
+ for (usage in usages) {
+ if (usage is KotlinSafeDeleteOverridingUsageInfo) {
+ overridingMethodUsages.add(usage)
+ } else {
+ result.add(usage)
+ }
+ }
+
+ if (!overridingMethodUsages.isEmpty()) {
+ if (ApplicationManager.getApplication()!!.isUnitTestMode()) {
+ result.addAll(overridingMethodUsages)
+ } else {
+ val dialog = KotlinOverridingDialog(project, overridingMethodUsages)
+ dialog.show()
+
+ if (!dialog.isOK()) return null
+
+ result.addAll(dialog.getSelected())
+ }
+ }
+
+ return result.copyToArray()
+ }
+
+ override fun prepareForDeletion(element: PsiElement) {
+ when (element) {
+ is PsiMethod -> element.cleanUpOverrides()
+
+ is JetNamedFunction ->
+ if (!element.isLocal()) {
+ element.getRepresentativeLightMethod()?.cleanUpOverrides()
+ }
+
+ is JetProperty ->
+ if (!element.isLocal()) {
+ element.toLightMethods().forEach { method -> method.cleanUpOverrides() }
+ }
+
+ is JetTypeParameter ->
+ element.deleteElementAndCleanParent()
+
+ is JetParameter ->
+ JetPsiUtil.deleteElementWithDelimiters(element)
+ }
+ }
+
+ override fun getElementsToSearch(
+ element: PsiElement, module: Module?, allElementsToDelete: Collection
+ ): Collection? {
+ when (element) {
+ is JetParameter ->
+ return element.toPsiParameter()?.let { psiParameter ->
+ JetRefactoringUtil.checkParametersInMethodHierarchy(psiParameter)
+ } ?: Collections.singletonList(element)
+
+ is PsiParameter ->
+ return JetRefactoringUtil.checkParametersInMethodHierarchy(element)
+ }
+
+ if (ApplicationManager.getApplication()!!.isUnitTestMode()) return Collections.singletonList(element)
+
+ return when (element) {
+ is JetNamedFunction, is JetProperty ->
+ JetRefactoringUtil.checkSuperMethods(
+ element as JetDeclaration, allElementsToDelete, "super.methods.delete.with.usage.search"
+ )
+
+ else -> super.getElementsToSearch(element, module, allElementsToDelete)
+ }
+ }
+}
diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/utils.kt b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/utils.kt
index 2836c0b3292..d1892819d4d 100644
--- a/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/utils.kt
+++ b/idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/utils.kt
@@ -26,6 +26,27 @@ import org.jetbrains.jet.lang.psi.JetPsiUtil
import com.intellij.psi.search.searches.OverridingMethodsSearch
import org.jetbrains.jet.asJava.unwrapped
import java.util.ArrayList
+import org.jetbrains.jet.lang.psi.JetParameter
+import org.jetbrains.jet.lang.psi.JetDeclaration
+import org.jetbrains.jet.lang.psi.JetPropertyAccessor
+import org.jetbrains.jet.lang.psi.JetClassOrObject
+import org.jetbrains.jet.lang.psi.JetTypeParameter
+import org.jetbrains.jet.lang.psi.psiUtil.*
+
+public fun PsiElement.canDeleteElement(): Boolean {
+ if (isObjectLiteral()) return false
+
+ if (this is JetParameter) {
+ val declaration = getParentByType(javaClass(), true)
+ return declaration != null && !(declaration is JetPropertyAccessor && declaration.isSetter())
+ }
+
+ return this is JetClassOrObject
+ || this is JetNamedFunction
+ || this is PsiMethod
+ || this is JetProperty
+ || this is JetTypeParameter
+}
fun PsiElement.removeOverrideModifier() {
val modifier = when (this) {