Translate KotlinSafeDeleteProcessor to Kotlin
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
<root>
|
||||
<item
|
||||
name='com.intellij.openapi.util.Conditions com.intellij.openapi.util.Condition<T> or(com.intellij.openapi.util.Condition<T>, com.intellij.openapi.util.Condition<T>)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='com.intellij.openapi.util.Key com.intellij.openapi.util.Key<T> create(java.lang.String)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
<item name='com.intellij.psi.PsiElement com.intellij.psi.PsiElement replace(com.intellij.psi.PsiElement)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='com.intellij.psi.PsiReference com.intellij.psi.PsiElement getElement()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.psi.PsiReferenceService java.util.List<com.intellij.psi.PsiReference> getReferences(com.intellij.psi.PsiElement, com.intellij.psi.PsiReferenceService.Hints)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
|
||||
@@ -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)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.psi.search.searches.ReferencesSearch com.intellij.util.Query<com.intellij.psi.PsiReference> search(com.intellij.psi.PsiElement)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun search(element: PsiElement): Query<PsiReference>""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.psi.search.searches.ReferencesSearch com.intellij.util.Query<com.intellij.psi.PsiReference> search(com.intellij.psi.PsiElement, com.intellij.psi.search.SearchScope)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun search(element: PsiElement, searchScope: SearchScope): Query<PsiReference>""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.psi.search.searches.ReferencesSearch com.intellij.util.Query<com.intellij.psi.PsiReference> search(com.intellij.psi.PsiElement, com.intellij.psi.search.SearchScope, boolean)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value"
|
||||
val=""fun search(element: PsiElement, searchScope: SearchScope, ignoreAccessScope: Boolean): Query<PsiReference>""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.psi.search.searches.ReferencesSearch com.intellij.util.Query<com.intellij.psi.PsiReference> search(com.intellij.psi.search.searches.ReferencesSearch.SearchParameters)'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
</root>
|
||||
@@ -0,0 +1,98 @@
|
||||
<root>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.JavaSafeDeleteDelegate void createUsageInfoForParameter(com.intellij.psi.PsiReference, java.util.List<com.intellij.usageView.UsageInfo>, com.intellij.psi.PsiParameter, com.intellij.psi.PsiMethod)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value"
|
||||
val=""fun createUsageInfoForParameter(reference: PsiReference, usages: MutableList<UsageInfo>, parameter: PsiParameter, method: PsiMethod): Unit""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor java.util.Collection<? extends com.intellij.psi.PsiElement> getElementsToSearch(com.intellij.psi.PsiElement, com.intellij.openapi.module.Module, java.util.Collection<com.intellij.psi.PsiElement>)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value"
|
||||
val=""fun getElementsToSearch(element: PsiElement, module: Module?, allElementsToDelete: Collection<PsiElement>): Collection<out PsiElement>?""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate boolean handlesElement(com.intellij.psi.PsiElement)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun handlesElement(element: PsiElement): Boolean""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate boolean isToSearchForTextOccurrences(com.intellij.psi.PsiElement)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun isToSearchForTextOccurrences(element: PsiElement): Boolean""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate boolean isToSearchInComments(com.intellij.psi.PsiElement)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun isToSearchInComments(element: PsiElement): Boolean""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate com.intellij.refactoring.safeDelete.NonCodeUsageSearchInfo findUsages(com.intellij.psi.PsiElement, com.intellij.psi.PsiElement[], java.util.List<com.intellij.usageView.UsageInfo>)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value"
|
||||
val=""fun findUsages(element: PsiElement, allElementsToDelete: Array<out PsiElement>, result: MutableList<UsageInfo>): NonCodeUsageSearchInfo?""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate com.intellij.usageView.UsageInfo[] preprocessUsages(com.intellij.openapi.project.Project, com.intellij.usageView.UsageInfo[])'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value"
|
||||
val=""fun preprocessUsages(project: Project, usages: Array<out UsageInfo>): Array<UsageInfo>?""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate java.util.Collection<? extends com.intellij.psi.PsiElement> getElementsToSearch(com.intellij.psi.PsiElement, java.util.Collection<com.intellij.psi.PsiElement>)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value"
|
||||
val=""fun getElementsToSearch(element: PsiElement, allElementsToDelete: Collection<PsiElement>): Collection<out PsiElement>?""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate java.util.Collection<com.intellij.psi.PsiElement> getAdditionalElementsToDelete(com.intellij.psi.PsiElement, java.util.Collection<com.intellij.psi.PsiElement>, boolean)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value"
|
||||
val=""fun getAdditionalElementsToDelete(element: PsiElement, allElementsToDelete: Collection<PsiElement>, askUser: Boolean): MutableCollection<PsiElement>?""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate java.util.Collection<java.lang.String> findConflicts(com.intellij.psi.PsiElement, com.intellij.psi.PsiElement[])'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value"
|
||||
val=""fun findConflicts(element: PsiElement, allElementsToDelete: Array<out PsiElement>): MutableCollection<String>?""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate void prepareForDeletion(com.intellij.psi.PsiElement)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun prepareForDeletion(element: PsiElement): Unit""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate void setToSearchForTextOccurrences(com.intellij.psi.PsiElement, boolean)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun setToSearchForTextOccurrences(element: PsiElement, enabled: Boolean): Unit""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegate void setToSearchInComments(com.intellij.psi.PsiElement, boolean)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value" val=""fun setToSearchInComments(element: PsiElement, enabled: Boolean): Unit""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegateBase java.util.Collection<? extends com.intellij.psi.PsiElement> getElementsToSearch(com.intellij.psi.PsiElement, com.intellij.openapi.module.Module, java.util.Collection<com.intellij.psi.PsiElement>)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value"
|
||||
val=""fun getElementsToSearch(element: PsiElement, module: Module?, allElementsToDelete: Collection<PsiElement>): Collection<out PsiElement>?""/>
|
||||
</annotation>
|
||||
</item>
|
||||
<item
|
||||
name='com.intellij.refactoring.safeDelete.SafeDeleteProcessorDelegateBase java.util.Collection<? extends com.intellij.psi.PsiElement> getElementsToSearch(com.intellij.psi.PsiElement, java.util.Collection<com.intellij.psi.PsiElement>)'>
|
||||
<annotation name='jet.runtime.typeinfo.KotlinSignature'>
|
||||
<val name="value"
|
||||
val=""fun getElementsToSearch(element: PsiElement, allElementsToDelete: Collection<PsiElement>): Collection<out PsiElement>?""/>
|
||||
</annotation>
|
||||
</item>
|
||||
</root>
|
||||
@@ -0,0 +1,8 @@
|
||||
<root>
|
||||
<item name='com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteUsageInfo com.intellij.psi.PsiElement getReferencedElement()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteUsageInfo myReferencedElement'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
</root>
|
||||
@@ -0,0 +1,8 @@
|
||||
<root>
|
||||
<item name='com.intellij.usageView.UsageInfo com.intellij.psi.SmartPsiElementPointer<?> getSmartPointer()'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='com.intellij.usageView.UsageInfo mySmartPointer'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
</root>
|
||||
@@ -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<PsiElement> =
|
||||
when (this) {
|
||||
|
||||
@@ -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<out CallableMemberDescriptor>")
|
||||
@NotNull
|
||||
@Override
|
||||
Set<? extends CallableMemberDescriptor> getOverriddenDescriptors();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<PsiElement>?, actionStringKey: String): MutableList<out PsiElement>?")
|
||||
@Nullable
|
||||
public static List<? extends PsiElement> checkSuperMethods(
|
||||
@NotNull JetDeclaration declaration, @Nullable Collection<PsiElement> ignore, @NotNull String actionStringKey
|
||||
@@ -287,6 +290,7 @@ public class JetRefactoringUtil {
|
||||
return "class " + classOrObject.getName();
|
||||
}
|
||||
|
||||
@KotlinSignature("fun checkParametersInMethodHierarchy(parameter: PsiParameter): MutableCollection<out PsiElement>?")
|
||||
@Nullable
|
||||
public static Collection<? extends PsiElement> checkParametersInMethodHierarchy(@NotNull PsiParameter parameter) {
|
||||
PsiMethod method = (PsiMethod)parameter.getDeclarationScope();
|
||||
|
||||
+16
@@ -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;
|
||||
|
||||
@@ -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<UsageInfo>")
|
||||
public ArrayList<UsageInfo> getSelected() {
|
||||
ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();
|
||||
for (int i = 0; i < myChecked.length; i++) {
|
||||
|
||||
-460
@@ -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<PsiElement> getCondition(final Collection<? extends PsiElement> ignoredElements) {
|
||||
return new Condition<PsiElement>() {
|
||||
@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<UsageInfo> 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<UsageInfo> result
|
||||
) {
|
||||
return new NonCodeUsageSearchInfo(
|
||||
delegateToJavaProcessorAndCombineConditions(
|
||||
AsJavaPackage.toLightElements(jetDeclaration),
|
||||
getCondition(Arrays.asList(allElementsToDelete)),
|
||||
allElementsToDelete,
|
||||
result
|
||||
),
|
||||
jetDeclaration
|
||||
);
|
||||
}
|
||||
|
||||
private Condition<PsiElement> delegateToJavaProcessorAndCombineConditions(
|
||||
Iterable<? extends PsiElement> elements,
|
||||
Condition<PsiElement> insideDeleted,
|
||||
PsiElement[] allElementsToDelete,
|
||||
List<UsageInfo> 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<UsageInfo> result
|
||||
) {
|
||||
if (element == null) return null;
|
||||
|
||||
List<UsageInfo> javaUsages = new ArrayList<UsageInfo>();
|
||||
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<PsiMethod>() {
|
||||
@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<UsageInfo> result
|
||||
) {
|
||||
ReferencesSearch.search(declaration, declaration.getUseScope()).forEach(new Processor<PsiReference>() {
|
||||
@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<UsageInfo> result
|
||||
) {
|
||||
JetTypeParameterListOwner owner = PsiTreeUtil.getParentOfType(parameter, JetTypeParameterListOwner.class);
|
||||
if (owner == null) return;
|
||||
|
||||
List<JetTypeParameter> parameterList = owner.getTypeParameters();
|
||||
final int parameterIndex = parameterList.indexOf(parameter);
|
||||
|
||||
ReferencesSearch.search(owner).forEach(
|
||||
new Processor<PsiReference>() {
|
||||
@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<UsageInfo> 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<JetTypeProjection> projections = argList.getArguments();
|
||||
if (parameterIndex < projections.size()) {
|
||||
result.add(new SafeDeleteTypeArgumentListUsageInfo(projections.get(parameterIndex), parameter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Collection<String> 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<String> messages = new ArrayList<String>();
|
||||
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<UsageInfo> result = new ArrayList<UsageInfo>();
|
||||
ArrayList<UsageInfo> overridingMethodUsages = new ArrayList<UsageInfo>();
|
||||
|
||||
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<PsiElement> 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);
|
||||
}
|
||||
}
|
||||
+310
@@ -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<out PsiElement>, usages: MutableList<UsageInfo>
|
||||
): NonCodeUsageSearchInfo {
|
||||
val deleteList = allElementsToDelete.toList()
|
||||
|
||||
fun getIgnoranceCondition(): Condition<PsiElement> {
|
||||
return object : Condition<PsiElement> {
|
||||
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<UsageInfo>()
|
||||
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<JetValueArgumentName>()) != null) null
|
||||
else {
|
||||
usageElement.getParentByType(javaClass<JetImportDirective>())?.let { importDirective ->
|
||||
SafeDeleteImportDirectiveUsageInfo(importDirective, element.unwrapped as JetDeclaration)
|
||||
} ?: usageInfo
|
||||
}
|
||||
}
|
||||
|
||||
else -> usageInfo
|
||||
}
|
||||
}.filterNotNull().toCollection(usages)
|
||||
|
||||
return searchInfo
|
||||
}
|
||||
|
||||
fun findUsagesByJavaProcessor(elements: Iterator<PsiElement>, insideDeleted: Condition<PsiElement>): Condition<PsiElement> =
|
||||
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<JetImportDirective>())?.let { importDirective ->
|
||||
SafeDeleteImportDirectiveUsageInfo(importDirective, element.unwrapped as JetDeclaration)
|
||||
} ?: SafeDeleteReferenceSimpleDeleteUsageInfo(element, declaration, false)
|
||||
}
|
||||
|
||||
return getSearchInfo(declaration)
|
||||
}
|
||||
|
||||
fun findTypeParameterUsages(parameter: JetTypeParameter) {
|
||||
val owner = parameter.getParentByType(javaClass<JetTypeParameterListOwner>())
|
||||
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<JetUserType>())?.let { jetType ->
|
||||
jetType.getTypeArgumentList()
|
||||
} ?: referencedElement.getParentByType(javaClass<JetCallExpression>())?.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<out PsiElement>): MutableCollection<String>? {
|
||||
if (element is JetNamedFunction || element is JetProperty) {
|
||||
val jetClass = element.getParentByType(javaClass<JetClass>())
|
||||
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<String>()) { 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<out UsageInfo>): Array<UsageInfo>? {
|
||||
val result = ArrayList<UsageInfo>()
|
||||
val overridingMethodUsages = ArrayList<UsageInfo>()
|
||||
|
||||
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<PsiElement>
|
||||
): Collection<PsiElement>? {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<JetDeclaration>(), 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) {
|
||||
|
||||
Reference in New Issue
Block a user