Implement "Safe Delete" refactoring for properties
This commit is contained in:
@@ -910,4 +910,11 @@ public class JetPsiUtil {
|
||||
|
||||
return (names.size() > partIndex) ? names.get(partIndex) : header.getLastPartExpression();
|
||||
}
|
||||
|
||||
public static PsiElement ascendIfPropertyAccessor(PsiElement element) {
|
||||
if (element instanceof JetPropertyAccessor) {
|
||||
return element.getParent();
|
||||
}
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -410,20 +410,23 @@ public class GenerateTests {
|
||||
"idea/tests/",
|
||||
"JetSafeDeleteTestGenerated",
|
||||
AbstractJetSafeDeleteTest.class,
|
||||
testModel("idea/testData/safeDelete/deleteClass", "doClassTest"),
|
||||
testModel("idea/testData/safeDelete/deleteObject", "doObjectTest"),
|
||||
testModel("idea/testData/safeDelete/deleteFunction", "doFunctionTest"),
|
||||
testModel("idea/testData/safeDelete/deleteFunctionWithJavaUsages", "doFunctionTestWithJava")
|
||||
// TODO fix -- disabled because doesn't work in Idea 130.1335
|
||||
// testModel("idea/testData/safeDelete/deleteJavaMethod", "doJavaMethodTest")
|
||||
testModel("idea/testData/safeDelete/deleteClass/kotlinClass", "doClassTest"),
|
||||
testModel("idea/testData/safeDelete/deleteObject/kotlinObject", "doObjectTest"),
|
||||
testModel("idea/testData/safeDelete/deleteFunction/kotlinFunction", "doFunctionTest"),
|
||||
testModel("idea/testData/safeDelete/deleteFunction/kotlinFunctionWithJava", "doFunctionTestWithJava"),
|
||||
testModel("idea/testData/safeDelete/deleteFunction/javaFunctionWithKotlin", "doJavaMethodTest"),
|
||||
testModel("idea/testData/safeDelete/deleteProperty/kotlinProperty", "doPropertyTest"),
|
||||
testModel("idea/testData/safeDelete/deleteProperty/kotlinPropertyWithJava", "doPropertyTestWithJava"),
|
||||
testModel("idea/testData/safeDelete/deleteProperty/javaPropertyWithKotlin", "doJavaPropertyTest"),
|
||||
testModel("idea/testData/safeDelete/deleteTypeParameter/kotlinTypeParameter", "doTypeParameterTest"),
|
||||
testModel("idea/testData/safeDelete/deleteValueParameter/kotlinValueParameter", "doValueParameterTest")
|
||||
);
|
||||
|
||||
generateTest(
|
||||
"idea/tests/",
|
||||
"ReferenceResolveTestGenerated",
|
||||
AbstractResolveBaseTest.class,
|
||||
testModel("idea/testData/resolve/references", "doTest")
|
||||
);
|
||||
testModel("idea/testData/resolve/references", "doTest") );
|
||||
}
|
||||
|
||||
private static SimpleTestClassModel testModel(@NotNull String rootPath) {
|
||||
|
||||
@@ -258,4 +258,7 @@ usageType.selector = Selector
|
||||
x.in.y={0} in {1}
|
||||
x.implements.y={0} in {1} implements {2} in {3}.
|
||||
x.overrides.y.in.class.list={0} in {1} overrides functions in the following classes/traits: {2} Do you want to delete (with usage search) the base methods?
|
||||
unused.overriding.methods.title=Unused Overriding Methods
|
||||
unused.overriding.methods.title=Unused Overriding Members
|
||||
there.are.unused.methods.that.override.methods.you.delete=There are unused members that override methods you delete.
|
||||
choose.the.ones.you.want.to.be.deleted=Choose the ones you want to be deleted.
|
||||
method.column=Member
|
||||
+16
-18
@@ -22,22 +22,20 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Splitter;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.ui.BooleanTableCellRenderer;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.usages.impl.UsagePreviewPanel;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.java.JetClsMethod;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
@@ -78,22 +76,21 @@ class KotlinOverridingMethodsDialog extends DialogWrapper {
|
||||
|
||||
myMethodText = new String[myOverridingMethods.size()];
|
||||
for (int i = 0; i < myMethodText.length; i++) {
|
||||
myMethodText[i] = formatMethod(((KotlinSafeDeleteOverridingMethodUsageInfo) myOverridingMethods.get(i)).getOverridingMethod());
|
||||
myMethodText[i] = formatElement(((KotlinSafeDeleteOverridingUsageInfo) myOverridingMethods.get(i)).getOverridingElement());
|
||||
}
|
||||
myUsagePreviewPanel = new UsagePreviewPanel(project);
|
||||
setTitle(JetBundle.message("unused.overriding.methods.title"));
|
||||
init();
|
||||
}
|
||||
|
||||
private static String formatMethod(PsiMethod method) {
|
||||
if (method instanceof JetClsMethod) {
|
||||
JetNamedFunction function = (JetNamedFunction) ((JetClsMethod) method).getOrigin();
|
||||
|
||||
private static String formatElement(PsiElement element) {
|
||||
element = JetPsiUtil.ascendIfPropertyAccessor(element);
|
||||
if (element instanceof JetNamedFunction || element instanceof JetProperty) {
|
||||
BindingContext bindingContext =
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) function.getContainingFile()).getBindingContext();
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext();
|
||||
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, function);
|
||||
if (declarationDescriptor instanceof FunctionDescriptor) {
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
||||
if (declarationDescriptor instanceof CallableMemberDescriptor) {
|
||||
DeclarationDescriptor containingDescriptor = declarationDescriptor.getContainingDeclaration();
|
||||
if (containingDescriptor instanceof ClassDescriptor) {
|
||||
return JetBundle.message(
|
||||
@@ -105,7 +102,8 @@ class KotlinOverridingMethodsDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
return KotlinSafeDeleteProcessor.formatPsiMethod(method, true, false);
|
||||
assert element instanceof PsiMethod;
|
||||
return KotlinSafeDeleteProcessor.formatPsiMethod((PsiMethod) element, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -138,8 +136,8 @@ class KotlinOverridingMethodsDialog extends DialogWrapper {
|
||||
protected JComponent createNorthPanel() {
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
||||
panel.add(new JLabel(RefactoringBundle.message("there.are.unused.methods.that.override.methods.you.delete")));
|
||||
panel.add(new JLabel(RefactoringBundle.message("choose.the.ones.you.want.to.be.deleted")));
|
||||
panel.add(new JLabel(JetBundle.message("there.are.unused.methods.that.override.methods.you.delete")));
|
||||
panel.add(new JLabel(JetBundle.message("choose.the.ones.you.want.to.be.deleted")));
|
||||
return panel;
|
||||
}
|
||||
|
||||
@@ -245,7 +243,7 @@ class KotlinOverridingMethodsDialog extends DialogWrapper {
|
||||
case CHECK_COLUMN:
|
||||
return " ";
|
||||
default:
|
||||
return RefactoringBundle.message("method.column");
|
||||
return JetBundle.message("method.column");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-16
@@ -17,32 +17,23 @@
|
||||
package org.jetbrains.jet.plugin.refactoring.safeDelete;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteCustomUsageInfo;
|
||||
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteUsageInfo;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.jet.asJava.LightClassUtil;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiUtil;
|
||||
|
||||
public class KotlinSafeDeleteOverridingMethodUsageInfo extends SafeDeleteUsageInfo implements SafeDeleteCustomUsageInfo {
|
||||
public KotlinSafeDeleteOverridingMethodUsageInfo(PsiElement overridingMethod, PsiElement method) {
|
||||
super(toPsiMethod(overridingMethod), toPsiMethod(method));
|
||||
public class KotlinSafeDeleteOverridingUsageInfo extends SafeDeleteUsageInfo implements SafeDeleteCustomUsageInfo {
|
||||
public KotlinSafeDeleteOverridingUsageInfo(PsiElement overridingElement, PsiElement superElement) {
|
||||
super(overridingElement, superElement);
|
||||
}
|
||||
|
||||
protected static PsiMethod toPsiMethod(PsiElement element) {
|
||||
if (element instanceof JetNamedFunction) {
|
||||
element = LightClassUtil.getLightClassMethod((JetNamedFunction) element);
|
||||
}
|
||||
return element instanceof PsiMethod ? (PsiMethod) element : null;
|
||||
}
|
||||
|
||||
public PsiMethod getOverridingMethod() {
|
||||
return toPsiMethod(getElement());
|
||||
public PsiElement getOverridingElement() {
|
||||
return getElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performRefactoring() throws IncorrectOperationException {
|
||||
PsiElement element = getElement();
|
||||
PsiElement element = JetPsiUtil.ascendIfPropertyAccessor(getElement());
|
||||
if (element != null) {
|
||||
element.delete();
|
||||
}
|
||||
+148
-41
@@ -26,7 +26,6 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor;
|
||||
import com.intellij.refactoring.safeDelete.NonCodeUsageSearchInfo;
|
||||
@@ -39,9 +38,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.asJava.LightClassUtil;
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.Modality;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
@@ -58,7 +55,8 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
return element instanceof JetClassOrObject
|
||||
|| element instanceof JetObjectDeclarationName
|
||||
|| element instanceof JetNamedFunction
|
||||
|| element instanceof PsiMethod;
|
||||
|| element instanceof PsiMethod
|
||||
|| element instanceof JetProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -88,6 +86,14 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
if (element instanceof PsiMethod) {
|
||||
return findPsiMethodUsages((PsiMethod) element, allElementsToDelete, result);
|
||||
}
|
||||
if (element instanceof JetProperty) {
|
||||
JetProperty property = (JetProperty) element;
|
||||
|
||||
if (property.isLocal()) {
|
||||
return findLocalPropertyUsages(property, allElementsToDelete, result);
|
||||
}
|
||||
return findNonLocalPropertyUsages(property, allElementsToDelete, result);
|
||||
}
|
||||
return getDefaultNonCodeUsageSearchInfo(element, allElementsToDelete);
|
||||
}
|
||||
|
||||
@@ -156,7 +162,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
for (UsageInfo usageInfo : javaUsages) {
|
||||
if (usageInfo instanceof SafeDeleteOverridingMethodUsageInfo) {
|
||||
SafeDeleteOverridingMethodUsageInfo overrideUsageInfo = (SafeDeleteOverridingMethodUsageInfo) usageInfo;
|
||||
usageInfo = new KotlinSafeDeleteOverridingMethodUsageInfo(
|
||||
usageInfo = new KotlinSafeDeleteOverridingUsageInfo(
|
||||
overrideUsageInfo.getSmartPointer().getElement(), overrideUsageInfo.getReferencedElement()
|
||||
);
|
||||
}
|
||||
@@ -221,6 +227,86 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
);
|
||||
}
|
||||
|
||||
protected static NonCodeUsageSearchInfo findNonLocalPropertyUsages(
|
||||
JetProperty property,
|
||||
final PsiElement[] allElementsToDelete,
|
||||
List<UsageInfo> result
|
||||
) {
|
||||
LightClassUtil.PropertyAccessorsPsiMethods propertyMethods = LightClassUtil.getLightClassPropertyMethods(property);
|
||||
PsiMethod getter = propertyMethods.getGetter();
|
||||
PsiMethod setter = propertyMethods.getSetter();
|
||||
|
||||
Collection<PsiReference> references = ReferencesSearch.search(property).findAll();
|
||||
|
||||
Collection<PsiMethod> getterOverriding =
|
||||
(getter != null) ? OverridingMethodsSearch.search(getter, true).findAll() : Collections.<PsiMethod>emptyList();
|
||||
Collection<PsiMethod> setterOverriding =
|
||||
(setter != null) ? OverridingMethodsSearch.search(setter, true).findAll() : Collections.<PsiMethod>emptyList();
|
||||
|
||||
List<PsiMethod> overridingMethods = new ArrayList<PsiMethod>();
|
||||
overridingMethods.addAll(getterOverriding);
|
||||
overridingMethods.addAll(setterOverriding);
|
||||
overridingMethods = difference(overridingMethods, allElementsToDelete);
|
||||
|
||||
for (PsiReference reference : references) {
|
||||
PsiElement element = reference.getElement();
|
||||
if (!isInside(element, allElementsToDelete) && !isInside(element, overridingMethods)) {
|
||||
JetImportDirective importDirective = PsiTreeUtil.getParentOfType(element, JetImportDirective.class, false);
|
||||
if (importDirective != null) {
|
||||
result.add(new SafeDeleteImportDirectiveUsageInfo(importDirective, property));
|
||||
}
|
||||
else {
|
||||
result.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, property, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<PsiMethod, Collection<PsiReference>> methodToReferences = new HashMap<PsiMethod, Collection<PsiReference>>();
|
||||
for (PsiMethod overridingMethod : overridingMethods) {
|
||||
Collection<PsiReference> overridingReferences =
|
||||
ReferencesSearch.search(
|
||||
overridingMethod instanceof JetClsMethod ? ((JetClsMethod) overridingMethod).getOrigin() : overridingMethod
|
||||
).findAll();
|
||||
methodToReferences.put(overridingMethod, overridingReferences);
|
||||
}
|
||||
final Set<PsiMethod> safeGetterOverriding =
|
||||
filterSafeOverridingMethods(getter, references, getterOverriding, methodToReferences, result, allElementsToDelete);
|
||||
final Set<PsiMethod> safeSetterOverriding =
|
||||
filterSafeOverridingMethods(setter, references, setterOverriding, methodToReferences, result, allElementsToDelete);
|
||||
|
||||
return new NonCodeUsageSearchInfo(
|
||||
new Condition<PsiElement>() {
|
||||
@Override
|
||||
public boolean value(PsiElement usage) {
|
||||
if (usage instanceof JetFile) return false;
|
||||
return isInside(usage, allElementsToDelete)
|
||||
|| isInside(usage, safeGetterOverriding)
|
||||
|| isInside(usage, safeSetterOverriding) ;
|
||||
}
|
||||
},
|
||||
property
|
||||
);
|
||||
}
|
||||
|
||||
protected static NonCodeUsageSearchInfo findLocalPropertyUsages(
|
||||
final JetProperty property,
|
||||
final PsiElement[] allElementsToDelete,
|
||||
final List<UsageInfo> result
|
||||
) {
|
||||
ReferencesSearch.search(property, property.getUseScope()).forEach(new Processor<PsiReference>() {
|
||||
@Override
|
||||
public boolean process(PsiReference reference) {
|
||||
PsiElement element = reference.getElement();
|
||||
if (!isInside(element, allElementsToDelete)) {
|
||||
result.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, property, false));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
return getDefaultNonCodeUsageSearchInfo(property, allElementsToDelete);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mostly copied from JavaSafeDeleteProcessor.validateOverridingMethods
|
||||
* Revision: d4fc033
|
||||
@@ -270,7 +356,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
|
||||
for (PsiMethod method : validOverriding) {
|
||||
if (method != originalMethod) {
|
||||
usages.add(new KotlinSafeDeleteOverridingMethodUsageInfo(method, originalMethod));
|
||||
usages.add(new KotlinSafeDeleteOverridingUsageInfo(method, originalMethod));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,6 +368,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
PsiMethod[] methods = method.findSuperMethods();
|
||||
for (PsiMethod superMethod: methods) {
|
||||
PsiElement relevantElement = superMethod instanceof JetClsMethod ? ((JetClsMethod) superMethod).getOrigin() : superMethod;
|
||||
relevantElement = JetPsiUtil.ascendIfPropertyAccessor(relevantElement);
|
||||
if (ArrayUtilRt.find(ignore, relevantElement) < 0 && !MethodSignatureUtil.isSuperMethod(originalMethod, superMethod)) {
|
||||
return true;
|
||||
}
|
||||
@@ -289,7 +376,6 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static String wrapOrSkip(String s, boolean inCode) {
|
||||
return inCode ? "<code>" + s + "</code>" : s;
|
||||
}
|
||||
@@ -339,6 +425,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
public static String formatPsiMethod(PsiMethod psiMethod, boolean showContainingClass, boolean inCode) {
|
||||
int options = PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS | PsiFormatUtilBase.SHOW_TYPE;
|
||||
if (showContainingClass) {
|
||||
//noinspection ConstantConditions
|
||||
options |= PsiFormatUtilBase.SHOW_CONTAINING_CLASS;
|
||||
}
|
||||
|
||||
@@ -350,7 +437,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
|
||||
@Override
|
||||
public Collection<String> findConflicts(PsiElement element, PsiElement[] allElementsToDelete) {
|
||||
if (element instanceof JetNamedFunction) {
|
||||
if (element instanceof JetNamedFunction || element instanceof JetProperty) {
|
||||
JetClass jetClass = PsiTreeUtil.getParentOfType(element, JetClass.class);
|
||||
if (jetClass == null || jetClass.getBody() != element.getParent()) return null;
|
||||
|
||||
@@ -361,16 +448,16 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext();
|
||||
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
||||
if (!(declarationDescriptor instanceof FunctionDescriptor)) return null;
|
||||
if (!(declarationDescriptor instanceof CallableMemberDescriptor)) return null;
|
||||
|
||||
List<String> messages = new ArrayList<String>();
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
|
||||
for (FunctionDescriptor overridenDescriptor : functionDescriptor.getOverriddenDescriptors()) {
|
||||
CallableMemberDescriptor callableDescriptor = (CallableMemberDescriptor) declarationDescriptor;
|
||||
for (CallableMemberDescriptor overridenDescriptor : callableDescriptor.getOverriddenDescriptors()) {
|
||||
if (overridenDescriptor.getModality() == Modality.ABSTRACT) {
|
||||
String message = JetBundle.message(
|
||||
"x.implements.y",
|
||||
formatFunction(functionDescriptor, bindingContext, true),
|
||||
formatClass(functionDescriptor.getContainingDeclaration(), bindingContext, true),
|
||||
formatFunction(callableDescriptor, bindingContext, true),
|
||||
formatClass(callableDescriptor.getContainingDeclaration(), bindingContext, true),
|
||||
formatFunction(overridenDescriptor, bindingContext, true),
|
||||
formatClass(overridenDescriptor.getContainingDeclaration(), bindingContext, true)
|
||||
);
|
||||
@@ -395,7 +482,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
ArrayList<UsageInfo> overridingMethodUsages = new ArrayList<UsageInfo>();
|
||||
|
||||
for (UsageInfo usage : usages) {
|
||||
if (usage instanceof KotlinSafeDeleteOverridingMethodUsageInfo) {
|
||||
if (usage instanceof KotlinSafeDeleteOverridingUsageInfo) {
|
||||
overridingMethodUsages.add(usage);
|
||||
}
|
||||
else {
|
||||
@@ -419,8 +506,8 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
}
|
||||
|
||||
private static void removeOverrideModifier(@NotNull PsiElement element) {
|
||||
if (element instanceof JetNamedFunction) {
|
||||
JetModifierList modifierList = ((JetNamedFunction) element).getModifierList();
|
||||
if (element instanceof JetNamedFunction || element instanceof JetProperty) {
|
||||
JetModifierList modifierList = ((JetModifierListOwner) element).getModifierList();
|
||||
if (modifierList == null) return;
|
||||
|
||||
PsiElement overrideModifier = modifierList.getModifier(JetTokens.OVERRIDE_KEYWORD);
|
||||
@@ -458,21 +545,41 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
|
||||
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) {
|
||||
cleanUpOverrides(getter);
|
||||
}
|
||||
if (setter != null) {
|
||||
cleanUpOverrides(setter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkPsiMethodEquality(PsiMethod method1, PsiMethod method2) {
|
||||
if (method1 instanceof JetClsMethod && method2 instanceof JetClsMethod) {
|
||||
return ((JetClsMethod) method1).getOrigin() == ((JetClsMethod) method2).getOrigin();
|
||||
}
|
||||
return method1 == method2;
|
||||
}
|
||||
|
||||
private static void cleanUpOverrides(PsiMethod method) {
|
||||
Collection<MethodSignatureBackedByPsiMethod> superMethods =
|
||||
SuperMethodsSearch.search(method, null, true, false).findAll();
|
||||
Collection<PsiMethod> overridingMethods = OverridingMethodsSearch.search(method, false).findAll();
|
||||
Collection<PsiMethod> superMethods = Arrays.asList(method.findSuperMethods(true));
|
||||
Collection<PsiMethod> overridingMethods = OverridingMethodsSearch.search(method, true).findAll();
|
||||
overrideLoop: for (PsiMethod overridingMethod : overridingMethods) {
|
||||
PsiElement overridingElement = overridingMethod instanceof JetClsMethod
|
||||
? ((JetClsMethod) overridingMethod).getOrigin()
|
||||
: overridingMethod;
|
||||
Collection<MethodSignatureBackedByPsiMethod> currentSuperMethods =
|
||||
SuperMethodsSearch.search(overridingMethod, null, true, false).findAll();
|
||||
|
||||
Collection<PsiMethod> currentSuperMethods = new ArrayList<PsiMethod>();
|
||||
ContainerUtil.addAll(currentSuperMethods, overridingMethod.findSuperMethods(true));
|
||||
currentSuperMethods.addAll(superMethods);
|
||||
for (MethodSignatureBackedByPsiMethod superMethod: currentSuperMethods) {
|
||||
if (superMethod.getMethod() != method) continue overrideLoop;
|
||||
for (PsiMethod superMethod: currentSuperMethods) {
|
||||
if (!checkPsiMethodEquality(superMethod, method)) continue overrideLoop;
|
||||
}
|
||||
|
||||
removeOverrideModifier(overridingElement);
|
||||
@@ -481,22 +588,22 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
|
||||
@Nullable
|
||||
private static Collection<? extends PsiElement> checkSuperMethods(
|
||||
@NotNull JetNamedFunction function, @Nullable Collection<PsiElement> ignore
|
||||
@NotNull JetDeclaration declaration, @Nullable Collection<PsiElement> ignore
|
||||
) {
|
||||
final BindingContext bindingContext =
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) function.getContainingFile()).getBindingContext();
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) declaration.getContainingFile()).getBindingContext();
|
||||
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, function);
|
||||
if (!(declarationDescriptor instanceof FunctionDescriptor)) return null;
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration);
|
||||
if (!(declarationDescriptor instanceof CallableMemberDescriptor)) return null;
|
||||
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
|
||||
Set<? extends FunctionDescriptor> overridenDescriptors = functionDescriptor.getOverriddenDescriptors();
|
||||
CallableMemberDescriptor callableDescriptor = (CallableMemberDescriptor) declarationDescriptor;
|
||||
Set<? extends CallableMemberDescriptor> overridenDescriptors = callableDescriptor.getOverriddenDescriptors();
|
||||
|
||||
Collection<? extends PsiElement> superMethods = ContainerUtil.map(
|
||||
overridenDescriptors,
|
||||
new Function<FunctionDescriptor, PsiElement>() {
|
||||
new Function<CallableMemberDescriptor, PsiElement>() {
|
||||
@Override
|
||||
public PsiElement fun(FunctionDescriptor descriptor) {
|
||||
public PsiElement fun(CallableMemberDescriptor descriptor) {
|
||||
return BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
||||
}
|
||||
}
|
||||
@@ -505,7 +612,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
superMethods.removeAll(ignore);
|
||||
}
|
||||
|
||||
if (superMethods.isEmpty()) return Collections.singletonList(function);
|
||||
if (superMethods.isEmpty()) return Collections.singletonList(declaration);
|
||||
|
||||
List<String> superClasses = ContainerUtil.map(
|
||||
superMethods,
|
||||
@@ -514,7 +621,7 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
public String fun(PsiElement element) {
|
||||
String description;
|
||||
|
||||
if (element instanceof JetNamedFunction) {
|
||||
if (element instanceof JetNamedFunction || element instanceof JetProperty) {
|
||||
DeclarationDescriptor descriptor =
|
||||
bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
||||
assert descriptor != null;
|
||||
@@ -541,19 +648,19 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
String superClassesStr = "\n" + StringUtil.join(superClasses, "");
|
||||
String message = JetBundle.message(
|
||||
"x.overrides.y.in.class.list",
|
||||
DescriptorRenderer.COMPACT.render(functionDescriptor),
|
||||
DescriptorRenderer.SOURCE_CODE_SHORT_NAMES_IN_TYPES.render(functionDescriptor.getContainingDeclaration()),
|
||||
DescriptorRenderer.COMPACT.render(callableDescriptor),
|
||||
DescriptorRenderer.SOURCE_CODE_SHORT_NAMES_IN_TYPES.render(callableDescriptor.getContainingDeclaration()),
|
||||
superClassesStr
|
||||
);
|
||||
|
||||
int exitCode = Messages.showYesNoCancelDialog(
|
||||
function.getProject(), message, IdeBundle.message("title.warning"), Messages.getQuestionIcon()
|
||||
declaration.getProject(), message, IdeBundle.message("title.warning"), Messages.getQuestionIcon()
|
||||
);
|
||||
switch (exitCode) {
|
||||
case Messages.YES:
|
||||
return superMethods;
|
||||
case Messages.NO:
|
||||
return Collections.singletonList(function);
|
||||
return Collections.singletonList(declaration);
|
||||
default:
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -568,8 +675,8 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
return Collections.singletonList(element);
|
||||
}
|
||||
|
||||
if (element instanceof JetNamedFunction) {
|
||||
return checkSuperMethods((JetNamedFunction) element, allElementsToDelete);
|
||||
if (element instanceof JetNamedFunction || element instanceof JetProperty) {
|
||||
return checkSuperMethods((JetDeclaration) element, allElementsToDelete);
|
||||
}
|
||||
return super.getElementsToSearch(element, module, allElementsToDelete);
|
||||
}
|
||||
@@ -583,4 +690,4 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
}
|
||||
return super.getAdditionalElementsToDelete(element, allElementsToDelete, askUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
abstract class C implements B {
|
||||
@Override
|
||||
public String <caret>getFoo() {
|
||||
return "C";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
abstract class C implements B {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
trait B {
|
||||
public val foo: String
|
||||
}
|
||||
|
||||
class D: B {
|
||||
public override val foo: String
|
||||
get() {
|
||||
return "D"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
trait B {
|
||||
public val foo: String
|
||||
}
|
||||
|
||||
class D: B {
|
||||
public override val foo: String
|
||||
get() {
|
||||
return "D"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class C implements B {
|
||||
@Override
|
||||
public String <caret>getFoo() {
|
||||
return "C";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
trait B {
|
||||
public val foo: String
|
||||
}
|
||||
|
||||
class D: B {
|
||||
public override val foo: String
|
||||
get() {
|
||||
return "D"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
method C.getFoo() implements method B.getFoo().
|
||||
@@ -0,0 +1,11 @@
|
||||
abstract class C implements B {
|
||||
@Override
|
||||
public String <caret>getFoo() {
|
||||
return "C";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
abstract class C implements B {
|
||||
|
||||
@Override
|
||||
public void setFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
trait B {
|
||||
public var foo: String
|
||||
}
|
||||
|
||||
class D: B {
|
||||
public override var foo: String
|
||||
get() {
|
||||
return "D"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
trait B {
|
||||
public var foo: String
|
||||
}
|
||||
|
||||
class D: B {
|
||||
public override var foo: String
|
||||
get() {
|
||||
return "D"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class C implements B {
|
||||
@Override
|
||||
public String <caret>getFoo() {
|
||||
return "C";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
trait B {
|
||||
public var foo: String
|
||||
}
|
||||
|
||||
class D: B {
|
||||
public override var foo: String
|
||||
get() {
|
||||
return "D"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
method C.getFoo() implements method B.getFoo().
|
||||
@@ -0,0 +1,11 @@
|
||||
abstract class C implements B {
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "C";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void <caret>setFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
abstract class C implements B {
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "C";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
trait B {
|
||||
public var foo: String
|
||||
}
|
||||
|
||||
class D: B {
|
||||
public override var foo: String
|
||||
get() {
|
||||
return "D"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
trait B {
|
||||
public var foo: String
|
||||
}
|
||||
|
||||
class D: B {
|
||||
public override var foo: String
|
||||
get() {
|
||||
return "D"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class C implements B {
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "C";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void <caret>setFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
trait B {
|
||||
public var foo: String
|
||||
}
|
||||
|
||||
class D: B {
|
||||
public override var foo: String
|
||||
get() {
|
||||
return "D"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
method C.setFoo(String) implements method B.setFoo(String).
|
||||
@@ -0,0 +1,10 @@
|
||||
trait A {
|
||||
val foo: String
|
||||
}
|
||||
|
||||
class B: A {
|
||||
override val <caret>foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
val foo: jet.String in final class B : A implements val foo: jet.String in trait A.
|
||||
@@ -0,0 +1,14 @@
|
||||
trait A {
|
||||
val foo: String
|
||||
}
|
||||
|
||||
trait Z {
|
||||
val foo: String
|
||||
}
|
||||
|
||||
class B: A, Z {
|
||||
override val <caret>foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
val foo: jet.String in final class B : A, Z implements val foo: jet.String in trait A.
|
||||
val foo: jet.String in final class B : A, Z implements val foo: jet.String in trait Z.
|
||||
@@ -0,0 +1,13 @@
|
||||
trait A {
|
||||
var foo: String
|
||||
}
|
||||
|
||||
class B: A {
|
||||
override var <caret>foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
var foo: jet.String in final class B : A implements var foo: jet.String in trait A.
|
||||
@@ -0,0 +1,17 @@
|
||||
trait A {
|
||||
var foo: String
|
||||
}
|
||||
|
||||
trait Z {
|
||||
var foo: String
|
||||
}
|
||||
|
||||
class B: A, Z {
|
||||
override var <caret>foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
var foo: jet.String in final class B : A, Z implements var foo: jet.String in trait A.
|
||||
var foo: jet.String in final class B : A, Z implements var foo: jet.String in trait Z.
|
||||
@@ -0,0 +1,10 @@
|
||||
trait A {
|
||||
val <caret>foo: String
|
||||
}
|
||||
|
||||
class B: A {
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
trait A {
|
||||
}
|
||||
|
||||
class B: A {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
trait A {
|
||||
var <caret>foo: String
|
||||
}
|
||||
|
||||
class B: A {
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
set(value: String) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
trait A {
|
||||
}
|
||||
|
||||
class B: A {
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
trait A {
|
||||
val <caret>foo: String
|
||||
}
|
||||
|
||||
trait Z {
|
||||
val foo: String
|
||||
}
|
||||
|
||||
class B: A, Z {
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
trait A {
|
||||
}
|
||||
|
||||
trait Z {
|
||||
val foo: String
|
||||
}
|
||||
|
||||
class B: A, Z {
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
trait A {
|
||||
var <caret>foo: String
|
||||
}
|
||||
|
||||
trait Z {
|
||||
var foo: String
|
||||
}
|
||||
|
||||
class B: A, Z {
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
set(value: String) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
trait A {
|
||||
}
|
||||
|
||||
trait Z {
|
||||
var foo: String
|
||||
}
|
||||
|
||||
class B: A, Z {
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
set(value: String) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class C {
|
||||
val <caret>foo: String
|
||||
get() {
|
||||
return "foo"
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class C {
|
||||
}
|
||||
|
||||
class B {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
open class A {
|
||||
open val foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
}
|
||||
|
||||
class B: A() {
|
||||
override val <caret>foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
open class A {
|
||||
open val foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
}
|
||||
|
||||
class B: A() {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
open class A {
|
||||
open val <caret>foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
}
|
||||
|
||||
class B: A() {
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
open class A {
|
||||
}
|
||||
|
||||
class B: A() {
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
open class A {
|
||||
open var foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
||||
class B: A() {
|
||||
override var <caret>foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
open class A {
|
||||
open var foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
||||
class B: A() {
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
open class A {
|
||||
open var <caret>foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
||||
class B: A() {
|
||||
override var foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
open class A {
|
||||
}
|
||||
|
||||
class B: A() {
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
open class A {
|
||||
open val foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
}
|
||||
|
||||
trait Z {
|
||||
val foo: String
|
||||
}
|
||||
|
||||
class B: A(), Z {
|
||||
override val <caret>foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
val foo: jet.String in final class B : A, Z implements val foo: jet.String in trait Z.
|
||||
@@ -0,0 +1,17 @@
|
||||
open class A {
|
||||
open val <caret>foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
}
|
||||
|
||||
trait Z {
|
||||
val foo: String
|
||||
}
|
||||
|
||||
class B: A(), Z {
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
open class A {
|
||||
}
|
||||
|
||||
trait Z {
|
||||
val foo: String
|
||||
}
|
||||
|
||||
class B: A(), Z {
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
open class A {
|
||||
open var foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
||||
trait Z {
|
||||
var foo: String
|
||||
}
|
||||
|
||||
class B: A(), Z {
|
||||
override var <caret>foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
var foo: jet.String in final class B : A, Z implements var foo: jet.String in trait Z.
|
||||
@@ -0,0 +1,23 @@
|
||||
open class A {
|
||||
open var <caret>foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
|
||||
trait Z {
|
||||
var foo: String
|
||||
}
|
||||
|
||||
class B: A(), Z {
|
||||
override var foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
open class A {
|
||||
}
|
||||
|
||||
trait Z {
|
||||
var foo: String
|
||||
}
|
||||
|
||||
class B: A(), Z {
|
||||
override var foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
set(value: String) {
|
||||
println()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
open class A {
|
||||
val <caret>foo: String
|
||||
get() {
|
||||
return "A"
|
||||
}
|
||||
}
|
||||
|
||||
class B: A {
|
||||
fun bar() {
|
||||
println(foo)
|
||||
}
|
||||
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
open class A {
|
||||
}
|
||||
|
||||
class B: A {
|
||||
fun bar() {
|
||||
println(foo)
|
||||
}
|
||||
|
||||
override val foo: String
|
||||
get() {
|
||||
return "B"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
import test.foo
|
||||
|
||||
val <caret>foo = "foo"
|
||||
|
||||
class B {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
class B {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package test
|
||||
|
||||
import test.foo
|
||||
|
||||
val <caret>foo = "foo"
|
||||
|
||||
class B {
|
||||
val ref = foo
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
Property foo has 1 usage that is not safe to delete.
|
||||
Of those 0 usages are in strings, comments, or non-code files.
|
||||
@@ -0,0 +1,6 @@
|
||||
class B implements A, Z {
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class B implements A, Z {
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
trait A {
|
||||
val <caret>foo: String
|
||||
}
|
||||
|
||||
trait Z {
|
||||
val foo: String
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
trait A {
|
||||
}
|
||||
|
||||
trait Z {
|
||||
val foo: String
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class B implements A {
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
class B implements A {
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
trait A {
|
||||
val <caret>foo: String
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
trait A {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class B implements A, Z {
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class B implements A, Z {
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
trait A {
|
||||
var <caret>foo: String
|
||||
}
|
||||
|
||||
trait Z {
|
||||
var foo: String
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
trait A {
|
||||
}
|
||||
|
||||
trait Z {
|
||||
var foo: String
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class B implements A {
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class B implements A {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
trait A {
|
||||
var <caret>foo: String
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
trait A {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class B extends A {
|
||||
void bar() {
|
||||
System.out.println(getFoo());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class B extends A {
|
||||
void bar() {
|
||||
System.out.println(getFoo());
|
||||
}
|
||||
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
open class A {
|
||||
open val <caret>foo: String = ""
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
open class A {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class B extends A {
|
||||
@Override
|
||||
String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
class B extends A {
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
open class A {
|
||||
open val <caret>foo: String = ""
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
open class A {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
class B extends A {
|
||||
void bar() {
|
||||
setFoo("");
|
||||
System.out.println(getFoo());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
class B extends A {
|
||||
void bar() {
|
||||
setFoo("");
|
||||
System.out.println(getFoo());
|
||||
}
|
||||
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
public void setFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
open class A {
|
||||
open var <caret>foo: String = ""
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
open class A {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class B extends A {
|
||||
@Override
|
||||
String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
@Override
|
||||
void setFoo(String value) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
class B extends A {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
open class A {
|
||||
open var <caret>foo: String = ""
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
open class A {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class B extends A implements Z {
|
||||
@Override
|
||||
public String getFoo() {
|
||||
return "foo";
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user