Translate KotlinSafeDeleteProcessor to Kotlin
This commit is contained in:
@@ -1,4 +1,8 @@
|
|||||||
<root>
|
<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)'>
|
<item name='com.intellij.openapi.util.Key com.intellij.openapi.util.Key<T> create(java.lang.String)'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
<item name='com.intellij.psi.PsiElement com.intellij.psi.PsiElement replace(com.intellij.psi.PsiElement)'>
|
<item name='com.intellij.psi.PsiElement com.intellij.psi.PsiElement replace(com.intellij.psi.PsiElement)'>
|
||||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</item>
|
||||||
|
<item name='com.intellij.psi.PsiReference com.intellij.psi.PsiElement getElement()'>
|
||||||
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
|
</item>
|
||||||
<item
|
<item
|
||||||
name='com.intellij.psi.PsiReferenceService java.util.List<com.intellij.psi.PsiReference> getReferences(com.intellij.psi.PsiElement, com.intellij.psi.PsiReferenceService.Hints)'>
|
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'/>
|
<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)'>
|
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'/>
|
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||||
</item>
|
</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>
|
</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 com.intellij.psi.PsiNamedElement
|
||||||
import org.jetbrains.jet.lang.psi.JetCallableDeclaration
|
import org.jetbrains.jet.lang.psi.JetCallableDeclaration
|
||||||
import org.jetbrains.jet.lang.psi.psiUtil.isExtensionDeclaration
|
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> =
|
fun JetDeclaration.toLightElements(): List<PsiElement> =
|
||||||
when (this) {
|
when (this) {
|
||||||
|
|||||||
@@ -16,11 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.lang.descriptors;
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
|
import jet.runtime.typeinfo.KotlinSignature;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public interface CallableMemberDescriptor extends CallableDescriptor, MemberDescriptor {
|
public interface CallableMemberDescriptor extends CallableDescriptor, MemberDescriptor {
|
||||||
|
@KotlinSignature("fun getOverriddenDescriptors(): MutableSet<out CallableMemberDescriptor>")
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
Set<? extends CallableMemberDescriptor> getOverriddenDescriptors();
|
Set<? extends CallableMemberDescriptor> getOverriddenDescriptors();
|
||||||
|
|||||||
@@ -25,12 +25,12 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureHandler;
|
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeSignatureHandler;
|
||||||
import org.jetbrains.jet.plugin.refactoring.introduceVariable.JetIntroduceVariableHandler;
|
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 {
|
public class JetRefactoringSupportProvider extends RefactoringSupportProvider {
|
||||||
@Override
|
@Override
|
||||||
public boolean isSafeDeleteAvailable(@NotNull PsiElement element) {
|
public boolean isSafeDeleteAvailable(@NotNull PsiElement element) {
|
||||||
return KotlinSafeDeleteProcessor.canDeleteElement(element);
|
return SafeDeletePackage.canDeleteElement(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import com.intellij.psi.util.PsiFormatUtilBase;
|
|||||||
import com.intellij.ui.components.JBList;
|
import com.intellij.ui.components.JBList;
|
||||||
import com.intellij.util.Function;
|
import com.intellij.util.Function;
|
||||||
import com.intellij.util.containers.ContainerUtil;
|
import com.intellij.util.containers.ContainerUtil;
|
||||||
|
import jet.runtime.typeinfo.KotlinSignature;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.asJava.AsJavaPackage;
|
import org.jetbrains.jet.asJava.AsJavaPackage;
|
||||||
@@ -117,6 +118,8 @@ public class JetRefactoringUtil {
|
|||||||
return markAsJava ? "[Java] " + description : description;
|
return markAsJava ? "[Java] " + description : description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@KotlinSignature(
|
||||||
|
"fun checkSuperMethods(declaration: JetDeclaration, ignore: Collection<PsiElement>?, actionStringKey: String): MutableList<out PsiElement>?")
|
||||||
@Nullable
|
@Nullable
|
||||||
public static List<? extends PsiElement> checkSuperMethods(
|
public static List<? extends PsiElement> checkSuperMethods(
|
||||||
@NotNull JetDeclaration declaration, @Nullable Collection<PsiElement> ignore, @NotNull String actionStringKey
|
@NotNull JetDeclaration declaration, @Nullable Collection<PsiElement> ignore, @NotNull String actionStringKey
|
||||||
@@ -287,6 +290,7 @@ public class JetRefactoringUtil {
|
|||||||
return "class " + classOrObject.getName();
|
return "class " + classOrObject.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@KotlinSignature("fun checkParametersInMethodHierarchy(parameter: PsiParameter): MutableCollection<out PsiElement>?")
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Collection<? extends PsiElement> checkParametersInMethodHierarchy(@NotNull PsiParameter parameter) {
|
public static Collection<? extends PsiElement> checkParametersInMethodHierarchy(@NotNull PsiParameter parameter) {
|
||||||
PsiMethod method = (PsiMethod)parameter.getDeclarationScope();
|
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;
|
package org.jetbrains.jet.plugin.refactoring.safeDelete;
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import com.intellij.ui.ScrollPaneFactory;
|
|||||||
import com.intellij.ui.table.JBTable;
|
import com.intellij.ui.table.JBTable;
|
||||||
import com.intellij.usageView.UsageInfo;
|
import com.intellij.usageView.UsageInfo;
|
||||||
import com.intellij.usages.impl.UsagePreviewPanel;
|
import com.intellij.usages.impl.UsagePreviewPanel;
|
||||||
|
import jet.runtime.typeinfo.KotlinSignature;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
@@ -116,6 +117,7 @@ class KotlinOverridingDialog extends DialogWrapper {
|
|||||||
return "#org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinOverridingDialog";
|
return "#org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinOverridingDialog";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@KotlinSignature("fun getSelected(): ArrayList<UsageInfo>")
|
||||||
public ArrayList<UsageInfo> getSelected() {
|
public ArrayList<UsageInfo> getSelected() {
|
||||||
ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();
|
ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();
|
||||||
for (int i = 0; i < myChecked.length; i++) {
|
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 com.intellij.psi.search.searches.OverridingMethodsSearch
|
||||||
import org.jetbrains.jet.asJava.unwrapped
|
import org.jetbrains.jet.asJava.unwrapped
|
||||||
import java.util.ArrayList
|
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() {
|
fun PsiElement.removeOverrideModifier() {
|
||||||
val modifier = when (this) {
|
val modifier = when (this) {
|
||||||
|
|||||||
Reference in New Issue
Block a user