Implement "Safe Delete" refactoring for named functions
Conflicts: idea/src/org/jetbrains/jet/plugin/refactoring/safeDelete/KotlinSafeDeleteProcessor.java
This commit is contained in:
@@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
@@ -62,6 +63,11 @@ public class JetModifierList extends JetElementImpl {
|
||||
return getModifierNode(token) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getModifier(JetToken token) {
|
||||
return findChildByType(token);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ASTNode getModifierNode(JetToken token) {
|
||||
ASTNode node = getNode().getFirstChildNode();
|
||||
@@ -71,4 +77,6 @@ public class JetModifierList extends JetElementImpl {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -402,7 +402,10 @@ public class GenerateTests {
|
||||
"JetSafeDeleteTestGenerated",
|
||||
AbstractJetSafeDeleteTest.class,
|
||||
testModel("idea/testData/safeDelete/deleteClass", "doClassTest"),
|
||||
testModel("idea/testData/safeDelete/deleteObject", "doObjectTest")
|
||||
testModel("idea/testData/safeDelete/deleteObject", "doObjectTest"),
|
||||
testModel("idea/testData/safeDelete/deleteFunction", "doFunctionTest"),
|
||||
testModel("idea/testData/safeDelete/deleteFunctionWithJavaUsages", "doFunctionTestWithJava"),
|
||||
testModel("idea/testData/safeDelete/deleteJavaMethod", "doJavaMethodTest")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -227,7 +227,10 @@
|
||||
<elementDescriptionProvider implementation="org.jetbrains.jet.plugin.findUsages.JetElementDescriptionProvider"/>
|
||||
<findUsagesHandlerFactory implementation="org.jetbrains.jet.plugin.findUsages.KotlinFindUsagesHandlerFactory"/>
|
||||
<usageTypeProvider implementation="org.jetbrains.jet.plugin.findUsages.JetUsageTypeProvider"/>
|
||||
<refactoring.safeDeleteProcessor implementation="org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinSafeDeleteProcessor" id="kotlinProcessor"/>
|
||||
<refactoring.safeDeleteProcessor
|
||||
id="kotlinProcessor"
|
||||
implementation="org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinSafeDeleteProcessor"
|
||||
order="before javaProcessor"/>
|
||||
<debugger.positionManagerFactory implementation="org.jetbrains.jet.plugin.debugger.JetPositionManagerFactory"/>
|
||||
<codeInsight.implementMethod language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.ImplementMethodsHandler"/>
|
||||
<codeInsight.overrideMethod language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.OverrideMethodsHandler"/>
|
||||
|
||||
@@ -253,4 +253,9 @@ usageType.function.call = Function call
|
||||
usageType.extension.receiver.type = Extension receiver type
|
||||
usageType.super.type.qualifier = Super type qualifier
|
||||
usageType.receiver = Receiver
|
||||
usageType.selector = Selector
|
||||
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
|
||||
@@ -33,7 +33,7 @@ import org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinSafeDeleteProcessor
|
||||
public class JetRefactoringSupportProvider extends RefactoringSupportProvider {
|
||||
@Override
|
||||
public boolean isSafeDeleteAvailable(PsiElement element) {
|
||||
return KotlinSafeDeleteProcessor.checkElement(element);
|
||||
return KotlinSafeDeleteProcessor.canDeleteElement(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+295
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* 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.Disposable;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
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.PsiMethod;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.ui.BooleanTableCellRenderer;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
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.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.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;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.TableColumnModel;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* Mostly copied from com.intellij.refactoring.safeDelete.OverridingMethodsDialog
|
||||
* Revision: 14aa2e2
|
||||
* (replace PsiMethod formatting)
|
||||
*/
|
||||
class KotlinOverridingMethodsDialog extends DialogWrapper {
|
||||
private final List<UsageInfo> myOverridingMethods;
|
||||
private final String[] myMethodText;
|
||||
private final boolean[] myChecked;
|
||||
|
||||
private static final int CHECK_COLUMN = 0;
|
||||
private JBTable myTable;
|
||||
private final UsagePreviewPanel myUsagePreviewPanel;
|
||||
|
||||
public KotlinOverridingMethodsDialog(Project project, List<UsageInfo> overridingMethods) {
|
||||
super(project, true);
|
||||
myOverridingMethods = overridingMethods;
|
||||
myChecked = new boolean[myOverridingMethods.size()];
|
||||
for (int i = 0; i < myChecked.length; i++) {
|
||||
myChecked[i] = true;
|
||||
}
|
||||
|
||||
myMethodText = new String[myOverridingMethods.size()];
|
||||
for (int i = 0; i < myMethodText.length; i++) {
|
||||
myMethodText[i] = formatMethod(((KotlinSafeDeleteOverridingMethodUsageInfo) myOverridingMethods.get(i)).getOverridingMethod());
|
||||
}
|
||||
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();
|
||||
|
||||
BindingContext bindingContext =
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) function.getContainingFile()).getBindingContext();
|
||||
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, function);
|
||||
if (declarationDescriptor instanceof FunctionDescriptor) {
|
||||
DeclarationDescriptor containingDescriptor = declarationDescriptor.getContainingDeclaration();
|
||||
if (containingDescriptor instanceof ClassDescriptor) {
|
||||
return JetBundle.message(
|
||||
"x.in.y",
|
||||
DescriptorRenderer.COMPACT.render(declarationDescriptor),
|
||||
DescriptorRenderer.SOURCE_CODE_SHORT_NAMES_IN_TYPES.render(containingDescriptor)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return KotlinSafeDeleteProcessor.formatPsiMethod(method, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDimensionServiceKey() {
|
||||
return "#org.jetbrains.jet.plugin.refactoring.safeDelete.KotlinOverridingMethodsDialog";
|
||||
}
|
||||
|
||||
public ArrayList<UsageInfo> getSelected() {
|
||||
ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();
|
||||
for (int i = 0; i < myChecked.length; i++) {
|
||||
if (myChecked[i]) {
|
||||
result.add(myOverridingMethods.get(i));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Action[] createActions() {
|
||||
return new Action[] {getOKAction(), getCancelAction()};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doHelpAction() {
|
||||
HelpManager.getInstance().invokeHelp(HelpID.SAFE_DELETE_OVERRIDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
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")));
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myTable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dispose() {
|
||||
Disposer.dispose(myUsagePreviewPanel);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.setBorder(BorderFactory.createEmptyBorder(8, 0, 4, 0));
|
||||
final MyTableModel tableModel = new MyTableModel();
|
||||
myTable = new JBTable(tableModel);
|
||||
myTable.setShowGrid(false);
|
||||
|
||||
TableColumnModel columnModel = myTable.getColumnModel();
|
||||
int checkBoxWidth = new JCheckBox().getPreferredSize().width;
|
||||
columnModel.getColumn(CHECK_COLUMN).setCellRenderer(new BooleanTableCellRenderer());
|
||||
columnModel.getColumn(CHECK_COLUMN).setMaxWidth(checkBoxWidth);
|
||||
columnModel.getColumn(CHECK_COLUMN).setMinWidth(checkBoxWidth);
|
||||
|
||||
|
||||
// make SPACE check/uncheck selected rows
|
||||
InputMap inputMap = myTable.getInputMap();
|
||||
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable");
|
||||
ActionMap actionMap = myTable.getActionMap();
|
||||
actionMap.put("enable_disable", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (myTable.isEditing()) return;
|
||||
int[] rows = myTable.getSelectedRows();
|
||||
if (rows.length > 0) {
|
||||
boolean valueToBeSet = false;
|
||||
for (int row : rows) {
|
||||
if (!myChecked[row]) {
|
||||
valueToBeSet = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int row : rows) {
|
||||
myChecked[row] = valueToBeSet;
|
||||
}
|
||||
|
||||
tableModel.updateData();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
panel.setLayout(new BorderLayout());
|
||||
|
||||
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
|
||||
|
||||
panel.add(scrollPane, BorderLayout.CENTER);
|
||||
ListSelectionListener selectionListener = new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
int index = myTable.getSelectionModel().getLeadSelectionIndex();
|
||||
if (index != -1) {
|
||||
UsageInfo usageInfo = myOverridingMethods.get(index);
|
||||
myUsagePreviewPanel.updateLayout(Collections.singletonList(usageInfo));
|
||||
}
|
||||
else {
|
||||
myUsagePreviewPanel.updateLayout(null);
|
||||
}
|
||||
}
|
||||
};
|
||||
myTable.getSelectionModel().addListSelectionListener(selectionListener);
|
||||
|
||||
final Splitter splitter = new Splitter(true, 0.3f);
|
||||
splitter.setFirstComponent(panel);
|
||||
splitter.setSecondComponent(myUsagePreviewPanel);
|
||||
myUsagePreviewPanel.updateLayout(null);
|
||||
|
||||
Disposer.register(myDisposable, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
splitter.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
if (tableModel.getRowCount() != 0) {
|
||||
myTable.getSelectionModel().addSelectionInterval(0, 0);
|
||||
}
|
||||
return splitter;
|
||||
}
|
||||
|
||||
class MyTableModel extends AbstractTableModel {
|
||||
@Override
|
||||
public int getRowCount() {
|
||||
return myChecked.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getColumnName(int column) {
|
||||
switch (column) {
|
||||
case CHECK_COLUMN:
|
||||
return " ";
|
||||
default:
|
||||
return RefactoringBundle.message("method.column");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class getColumnClass(int columnIndex) {
|
||||
switch (columnIndex) {
|
||||
case CHECK_COLUMN:
|
||||
return Boolean.class;
|
||||
default:
|
||||
return String.class;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
if (columnIndex == CHECK_COLUMN) {
|
||||
return Boolean.valueOf(myChecked[rowIndex]);
|
||||
}
|
||||
else {
|
||||
return myMethodText[rowIndex];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
if (columnIndex == CHECK_COLUMN) {
|
||||
myChecked[rowIndex] = ((Boolean) aValue).booleanValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return columnIndex == CHECK_COLUMN;
|
||||
}
|
||||
|
||||
void updateData() {
|
||||
fireTableDataChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.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;
|
||||
|
||||
public class KotlinSafeDeleteOverridingMethodUsageInfo extends SafeDeleteUsageInfo implements SafeDeleteCustomUsageInfo {
|
||||
public KotlinSafeDeleteOverridingMethodUsageInfo(PsiElement overridingMethod, PsiElement method) {
|
||||
super(toPsiMethod(overridingMethod), toPsiMethod(method));
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performRefactoring() throws IncorrectOperationException {
|
||||
PsiElement element = getElement();
|
||||
if (element != null) {
|
||||
element.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
+480
-19
@@ -16,37 +16,54 @@
|
||||
|
||||
package org.jetbrains.jet.plugin.refactoring.safeDelete;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
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.util.PsiTreeUtil;
|
||||
import com.intellij.psi.search.searches.SuperMethodsSearch;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.safeDelete.JavaSafeDeleteProcessor;
|
||||
import com.intellij.refactoring.safeDelete.NonCodeUsageSearchInfo;
|
||||
import com.intellij.refactoring.safeDelete.SafeDeleteProcessor;
|
||||
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteOverridingMethodUsageInfo;
|
||||
import com.intellij.refactoring.safeDelete.usageInfo.SafeDeleteReferenceSimpleDeleteUsageInfo;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetImportDirective;
|
||||
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetObjectDeclarationName;
|
||||
import 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.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
|
||||
import org.jetbrains.jet.lang.resolve.java.JetClsMethod;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
import org.jetbrains.jet.plugin.JetBundle;
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
|
||||
import org.jetbrains.jet.renderer.DescriptorRenderer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
public static boolean checkElement(PsiElement element) {
|
||||
public static boolean canDeleteElement(PsiElement element) {
|
||||
return element instanceof JetClassOrObject
|
||||
|| element instanceof JetObjectDeclarationName;
|
||||
|| element instanceof JetObjectDeclarationName
|
||||
|| element instanceof JetNamedFunction
|
||||
|| element instanceof PsiMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handlesElement(PsiElement element) {
|
||||
return checkElement(element);
|
||||
return canDeleteElement(element);
|
||||
}
|
||||
|
||||
protected static NonCodeUsageSearchInfo getDefaultNonCodeUsageSearchInfo(
|
||||
@@ -61,12 +78,25 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
if (element instanceof JetClassOrObject) {
|
||||
return findClassOrObjectUsages(element, (JetClassOrObject) element, allElementsToDelete, result);
|
||||
}
|
||||
if (element instanceof JetObjectDeclarationName && element.getParent() instanceof JetObjectDeclaration) {
|
||||
return findClassOrObjectUsages(element, (JetObjectDeclaration) element.getParent(), allElementsToDelete, result);
|
||||
if (element instanceof JetObjectDeclarationName) {
|
||||
PsiElement parent = getObjectDeclarationOrFail(element);
|
||||
return findClassOrObjectUsages(element, (JetObjectDeclaration) parent, allElementsToDelete, result);
|
||||
}
|
||||
if (element instanceof JetNamedFunction) {
|
||||
return findFunctionUsages((JetNamedFunction) element, allElementsToDelete, result);
|
||||
}
|
||||
if (element instanceof PsiMethod) {
|
||||
return findPsiMethodUsages((PsiMethod) element, allElementsToDelete, result);
|
||||
}
|
||||
return getDefaultNonCodeUsageSearchInfo(element, allElementsToDelete);
|
||||
}
|
||||
|
||||
private static PsiElement getObjectDeclarationOrFail(PsiElement element) {
|
||||
PsiElement parent = element.getParent();
|
||||
assert parent instanceof JetObjectDeclaration;
|
||||
return parent;
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodOverridesPrivateMethodOfSuperclass")
|
||||
protected static boolean isInside(PsiElement place, PsiElement[] ancestors) {
|
||||
return isInside(place, Arrays.asList(ancestors));
|
||||
@@ -80,6 +110,14 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodOverridesStaticMethodOfSuperclass")
|
||||
public static boolean isInside(PsiElement place, PsiElement ancestor) {
|
||||
if (ancestor instanceof JetClsMethod) {
|
||||
ancestor = ((JetClsMethod) ancestor).getOrigin();
|
||||
}
|
||||
return JavaSafeDeleteProcessor.isInside(place, ancestor);
|
||||
}
|
||||
|
||||
protected static NonCodeUsageSearchInfo findClassOrObjectUsages(
|
||||
PsiElement referencedElement,
|
||||
final JetClassOrObject classOrObject,
|
||||
@@ -107,18 +145,441 @@ public class KotlinSafeDeleteProcessor extends JavaSafeDeleteProcessor {
|
||||
return getDefaultNonCodeUsageSearchInfo(referencedElement, allElementsToDelete);
|
||||
}
|
||||
|
||||
protected NonCodeUsageSearchInfo findPsiMethodUsages(
|
||||
PsiMethod method,
|
||||
PsiElement[] allElementsToDelete,
|
||||
List<UsageInfo> result
|
||||
) {
|
||||
List<UsageInfo> javaUsages = new ArrayList<UsageInfo>();
|
||||
NonCodeUsageSearchInfo searchInfo = super.findUsages(method, allElementsToDelete, javaUsages);
|
||||
|
||||
for (UsageInfo usageInfo : javaUsages) {
|
||||
if (usageInfo instanceof SafeDeleteOverridingMethodUsageInfo) {
|
||||
SafeDeleteOverridingMethodUsageInfo overrideUsageInfo = (SafeDeleteOverridingMethodUsageInfo) usageInfo;
|
||||
usageInfo = new KotlinSafeDeleteOverridingMethodUsageInfo(
|
||||
overrideUsageInfo.getSmartPointer().getElement(), overrideUsageInfo.getReferencedElement()
|
||||
);
|
||||
}
|
||||
result.add(usageInfo);
|
||||
}
|
||||
|
||||
return searchInfo;
|
||||
}
|
||||
|
||||
private static <T, C extends T> List<C> difference(Collection<C> from, T[] a) {
|
||||
List<C> list = new ArrayList<C>(from);
|
||||
list.removeAll(Arrays.asList(a));
|
||||
return list;
|
||||
}
|
||||
|
||||
protected static NonCodeUsageSearchInfo findFunctionUsages(
|
||||
JetNamedFunction function,
|
||||
final PsiElement[] allElementsToDelete,
|
||||
List<UsageInfo> result
|
||||
) {
|
||||
PsiMethod lightMethod = LightClassUtil.getLightClassMethod(function);
|
||||
if (lightMethod == null) {
|
||||
return getDefaultNonCodeUsageSearchInfo(function, allElementsToDelete);
|
||||
}
|
||||
|
||||
Collection<PsiReference> references = ReferencesSearch.search(function).findAll();
|
||||
List<PsiMethod> overridingMethods = difference(OverridingMethodsSearch.search(lightMethod, true).findAll(), 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, function));
|
||||
}
|
||||
else {
|
||||
result.add(new SafeDeleteReferenceSimpleDeleteUsageInfo(element, function, 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> safeOverriding =
|
||||
filterSafeOverridingMethods(lightMethod, references, overridingMethods, 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, safeOverriding);
|
||||
}
|
||||
},
|
||||
function
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mostly copied from JavaSafeDeleteProcessor.validateOverridingMethods
|
||||
* Revision: d4fc033
|
||||
* (simplified and implemented proper treatment of light methods)
|
||||
*/
|
||||
private static Set<PsiMethod> filterSafeOverridingMethods(
|
||||
PsiMethod originalMethod, Collection<PsiReference> originalReferences,
|
||||
Collection<PsiMethod> overridingMethods, HashMap<PsiMethod, Collection<PsiReference>> methodToReferences,
|
||||
List<UsageInfo> usages,
|
||||
PsiElement[] allElementsToDelete
|
||||
) {
|
||||
Set<PsiMethod> validOverriding = new LinkedHashSet<PsiMethod>(overridingMethods);
|
||||
boolean anyNewBadRefs;
|
||||
do {
|
||||
anyNewBadRefs = false;
|
||||
for (PsiMethod overridingMethod : overridingMethods) {
|
||||
if (validOverriding.contains(overridingMethod)) {
|
||||
Collection<PsiReference> overridingReferences = methodToReferences.get(overridingMethod);
|
||||
boolean anyOverridingRefs = false;
|
||||
for (PsiReference overridingReference : overridingReferences) {
|
||||
PsiElement element = overridingReference.getElement();
|
||||
if (!isInside(element, allElementsToDelete) && !isInside(element, validOverriding)) {
|
||||
anyOverridingRefs = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!anyOverridingRefs && isMultipleInterfacesImplementation(overridingMethod, originalMethod, allElementsToDelete)) {
|
||||
anyOverridingRefs = true;
|
||||
}
|
||||
|
||||
if (anyOverridingRefs) {
|
||||
validOverriding.remove(overridingMethod);
|
||||
anyNewBadRefs = true;
|
||||
|
||||
for (PsiReference reference : originalReferences) {
|
||||
PsiElement element = reference.getElement();
|
||||
if (!isInside(element, allElementsToDelete) && !isInside(element, overridingMethods)) {
|
||||
validOverriding.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (anyNewBadRefs && !validOverriding.isEmpty());
|
||||
|
||||
for (PsiMethod method : validOverriding) {
|
||||
if (method != originalMethod) {
|
||||
usages.add(new KotlinSafeDeleteOverridingMethodUsageInfo(method, originalMethod));
|
||||
}
|
||||
}
|
||||
|
||||
return validOverriding;
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodOverridesPrivateMethodOfSuperclass")
|
||||
private static boolean isMultipleInterfacesImplementation(PsiMethod method, PsiMethod originalMethod, PsiElement[] ignore) {
|
||||
PsiMethod[] methods = method.findSuperMethods();
|
||||
for (PsiMethod superMethod: methods) {
|
||||
PsiElement relevantElement = superMethod instanceof JetClsMethod ? ((JetClsMethod) superMethod).getOrigin() : superMethod;
|
||||
if (ArrayUtilRt.find(ignore, relevantElement) < 0 && !MethodSignatureUtil.isSuperMethod(originalMethod, superMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static String wrapOrSkip(String s, boolean inCode) {
|
||||
return inCode ? "<code>" + s + "</code>" : s;
|
||||
}
|
||||
|
||||
private static String formatClass(DeclarationDescriptor classDescriptor, BindingContext bindingContext, boolean inCode) {
|
||||
PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext, classDescriptor);
|
||||
if (element instanceof PsiClass) {
|
||||
return formatPsiClass((PsiClass) element, false, inCode);
|
||||
}
|
||||
|
||||
return wrapOrSkip(formatClassDescriptor(classDescriptor), inCode);
|
||||
}
|
||||
|
||||
private static String formatFunction(DeclarationDescriptor functionDescriptor, BindingContext bindingContext, boolean inCode) {
|
||||
PsiElement element = BindingContextUtils.descriptorToDeclaration(bindingContext, functionDescriptor);
|
||||
if (element instanceof PsiMethod) {
|
||||
return formatPsiMethod((PsiMethod) element, false, inCode);
|
||||
}
|
||||
|
||||
return wrapOrSkip(formatFunctionDescriptor(functionDescriptor), inCode);
|
||||
}
|
||||
|
||||
private static String formatClassDescriptor(DeclarationDescriptor classDescriptor) {
|
||||
return DescriptorRenderer.SOURCE_CODE_SHORT_NAMES_IN_TYPES.render(classDescriptor);
|
||||
}
|
||||
|
||||
private static String formatFunctionDescriptor(DeclarationDescriptor functionDescriptor) {
|
||||
return DescriptorRenderer.COMPACT.render(functionDescriptor);
|
||||
}
|
||||
|
||||
public static String formatPsiClass(PsiClass psiClass, boolean markAsJava, boolean inCode) {
|
||||
String description;
|
||||
|
||||
String kind = psiClass.isInterface() ? "interface " : "class ";
|
||||
description = kind + PsiFormatUtil.formatClass(
|
||||
psiClass,
|
||||
PsiFormatUtilBase.SHOW_CONTAINING_CLASS
|
||||
| PsiFormatUtilBase.SHOW_NAME
|
||||
| PsiFormatUtilBase.SHOW_PARAMETERS
|
||||
| PsiFormatUtilBase.SHOW_TYPE
|
||||
);
|
||||
description = wrapOrSkip(description, inCode);
|
||||
|
||||
return markAsJava ? "[Java] " + description : description;
|
||||
}
|
||||
|
||||
public static String formatPsiMethod(PsiMethod psiMethod, boolean showContainingClass, boolean inCode) {
|
||||
int options = PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS | PsiFormatUtilBase.SHOW_TYPE;
|
||||
if (showContainingClass) {
|
||||
options |= PsiFormatUtilBase.SHOW_CONTAINING_CLASS;
|
||||
}
|
||||
|
||||
String description = PsiFormatUtil.formatMethod(psiMethod, PsiSubstitutor.EMPTY, options, PsiFormatUtilBase.SHOW_TYPE);
|
||||
description = wrapOrSkip(description, inCode);
|
||||
|
||||
return "[Java] " + description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> findConflicts(PsiElement element, PsiElement[] allElementsToDelete) {
|
||||
if (element instanceof JetNamedFunction) {
|
||||
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 FunctionDescriptor)) return null;
|
||||
|
||||
List<String> messages = new ArrayList<String>();
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
|
||||
for (FunctionDescriptor overridenDescriptor : functionDescriptor.getOverriddenDescriptors()) {
|
||||
if (overridenDescriptor.getModality() == Modality.ABSTRACT) {
|
||||
String message = JetBundle.message(
|
||||
"x.implements.y",
|
||||
formatFunction(functionDescriptor, bindingContext, true),
|
||||
formatClass(functionDescriptor.getContainingDeclaration(), bindingContext, true),
|
||||
formatFunction(overridenDescriptor, bindingContext, true),
|
||||
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(Project project, UsageInfo[] usages) {
|
||||
return usages;
|
||||
ArrayList<UsageInfo> result = new ArrayList<UsageInfo>();
|
||||
ArrayList<UsageInfo> overridingMethodUsages = new ArrayList<UsageInfo>();
|
||||
|
||||
for (UsageInfo usage : usages) {
|
||||
if (usage instanceof KotlinSafeDeleteOverridingMethodUsageInfo) {
|
||||
overridingMethodUsages.add(usage);
|
||||
}
|
||||
else {
|
||||
result.add(usage);
|
||||
}
|
||||
}
|
||||
|
||||
if (!overridingMethodUsages.isEmpty()) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
result.addAll(overridingMethodUsages);
|
||||
}
|
||||
else {
|
||||
KotlinOverridingMethodsDialog dialog = new KotlinOverridingMethodsDialog(project, overridingMethodUsages);
|
||||
dialog.show();
|
||||
if (!dialog.isOK()) return null;
|
||||
result.addAll(dialog.getSelected());
|
||||
}
|
||||
}
|
||||
|
||||
return result.toArray(new UsageInfo[result.size()]);
|
||||
}
|
||||
|
||||
private static void removeOverrideModifier(@NotNull PsiElement element) {
|
||||
if (element instanceof JetNamedFunction) {
|
||||
JetModifierList modifierList = ((JetNamedFunction) element).getModifierList();
|
||||
if (modifierList == null) return;
|
||||
|
||||
PsiElement overrideModifier = modifierList.getModifier(JetTokens.OVERRIDE_KEYWORD);
|
||||
if (overrideModifier != null) {
|
||||
overrideModifier.delete();
|
||||
}
|
||||
}
|
||||
else if (element instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod) element;
|
||||
|
||||
PsiAnnotation overrideAnnotation = null;
|
||||
for (PsiAnnotation annotation : method.getModifierList().getAnnotations()) {
|
||||
if ("java.lang.Override".equals(annotation.getQualifiedName())) {
|
||||
overrideAnnotation = annotation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (overrideAnnotation != null) {
|
||||
overrideAnnotation.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareForDeletion(PsiElement element) throws IncorrectOperationException {
|
||||
if (element instanceof PsiMethod) {
|
||||
cleanUpOverrides((PsiMethod) element);
|
||||
}
|
||||
else if (element instanceof JetNamedFunction) {
|
||||
PsiMethod lightMethod = LightClassUtil.getLightClassMethod((JetNamedFunction) element);
|
||||
if (lightMethod == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
cleanUpOverrides(lightMethod);
|
||||
}
|
||||
}
|
||||
|
||||
private static void cleanUpOverrides(PsiMethod method) {
|
||||
Collection<MethodSignatureBackedByPsiMethod> superMethods =
|
||||
SuperMethodsSearch.search(method, null, true, false).findAll();
|
||||
Collection<PsiMethod> overridingMethods = OverridingMethodsSearch.search(method, false).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();
|
||||
currentSuperMethods.addAll(superMethods);
|
||||
for (MethodSignatureBackedByPsiMethod superMethod: currentSuperMethods) {
|
||||
if (superMethod.getMethod() != method) continue overrideLoop;
|
||||
}
|
||||
|
||||
removeOverrideModifier(overridingElement);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Collection<? extends PsiElement> checkSuperMethods(
|
||||
@NotNull JetNamedFunction function, @Nullable Collection<PsiElement> ignore
|
||||
) {
|
||||
final BindingContext bindingContext =
|
||||
AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) function.getContainingFile()).getBindingContext();
|
||||
|
||||
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, function);
|
||||
if (!(declarationDescriptor instanceof FunctionDescriptor)) return null;
|
||||
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
|
||||
Set<? extends FunctionDescriptor> overridenDescriptors = functionDescriptor.getOverriddenDescriptors();
|
||||
|
||||
Collection<? extends PsiElement> superMethods = ContainerUtil.map(
|
||||
overridenDescriptors,
|
||||
new Function<FunctionDescriptor, PsiElement>() {
|
||||
@Override
|
||||
public PsiElement fun(FunctionDescriptor descriptor) {
|
||||
return BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
|
||||
}
|
||||
}
|
||||
);
|
||||
if (ignore != null) {
|
||||
superMethods.removeAll(ignore);
|
||||
}
|
||||
|
||||
if (superMethods.isEmpty()) return Collections.singletonList(function);
|
||||
|
||||
List<String> superClasses = ContainerUtil.map(
|
||||
superMethods,
|
||||
new Function<PsiElement, String>() {
|
||||
@Override
|
||||
public String fun(PsiElement element) {
|
||||
String description;
|
||||
|
||||
if (element instanceof JetNamedFunction) {
|
||||
DeclarationDescriptor descriptor =
|
||||
bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
|
||||
assert descriptor != null;
|
||||
|
||||
DeclarationDescriptor containingDescriptor = descriptor.getContainingDeclaration();
|
||||
assert containingDescriptor != null;
|
||||
|
||||
description = formatClassDescriptor(containingDescriptor);
|
||||
}
|
||||
else {
|
||||
assert element instanceof PsiMethod;
|
||||
|
||||
PsiClass psiClass = ((PsiMethod) element).getContainingClass();
|
||||
assert psiClass != null;
|
||||
|
||||
description = formatPsiClass(psiClass, true, false);
|
||||
}
|
||||
|
||||
return " " + description + "\n";
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
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()),
|
||||
superClassesStr
|
||||
);
|
||||
|
||||
int exitCode = Messages.showYesNoCancelDialog(
|
||||
function.getProject(), message, IdeBundle.message("title.warning"), Messages.getQuestionIcon()
|
||||
);
|
||||
switch (exitCode) {
|
||||
case Messages.YES:
|
||||
return superMethods;
|
||||
case Messages.NO:
|
||||
return Collections.singletonList(function);
|
||||
default:
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Collection<? extends PsiElement> getElementsToSearch(
|
||||
PsiElement element, @Nullable Module module, Collection<PsiElement> allElementsToDelete
|
||||
) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
return Collections.singletonList(element);
|
||||
}
|
||||
|
||||
if (element instanceof JetNamedFunction) {
|
||||
return checkSuperMethods((JetNamedFunction) element, allElementsToDelete);
|
||||
}
|
||||
return super.getElementsToSearch(element, module, allElementsToDelete);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<PsiElement> getAdditionalElementsToDelete(
|
||||
PsiElement element, Collection<PsiElement> allElementsToDelete, boolean askUser
|
||||
) {
|
||||
if (element instanceof JetObjectDeclarationName && element.getParent() instanceof JetObjectDeclaration) {
|
||||
return Arrays.asList(element.getParent());
|
||||
if (element instanceof JetObjectDeclarationName) {
|
||||
return Arrays.asList(getObjectDeclarationOrFail(element));
|
||||
}
|
||||
return super.getAdditionalElementsToDelete(element, allElementsToDelete, askUser);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package test
|
||||
|
||||
import test.foo
|
||||
|
||||
fun <caret>foo() {
|
||||
|
||||
}
|
||||
|
||||
class B {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
class B {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package test
|
||||
|
||||
import test.foo
|
||||
|
||||
fun <caret>foo() {
|
||||
|
||||
}
|
||||
|
||||
class B {
|
||||
val ref = ::foo
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
Function 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,9 @@
|
||||
trait A {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
class B: A {
|
||||
override fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
fun foo(): jet.Unit in final class B : A implements fun foo(): jet.Unit in trait A.
|
||||
@@ -0,0 +1,13 @@
|
||||
trait A {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
trait Z {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
class B: A, Z {
|
||||
override fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fun foo(): jet.Unit in final class B : A, Z implements fun foo(): jet.Unit in trait A.
|
||||
fun foo(): jet.Unit in final class B : A, Z implements fun foo(): jet.Unit in trait Z.
|
||||
@@ -0,0 +1,7 @@
|
||||
class C {
|
||||
fun <caret>foo {
|
||||
}
|
||||
}
|
||||
|
||||
class B {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class C {
|
||||
}
|
||||
|
||||
class B {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
open class A {
|
||||
open fun foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class B: A {
|
||||
override fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
open class A {
|
||||
open fun foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class B: A {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
open class A {
|
||||
open fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class B: A {
|
||||
override fun foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
open class A {
|
||||
}
|
||||
|
||||
class B: A {
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
open class A {
|
||||
open fun foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
trait Z {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
class B: A, Z {
|
||||
override fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
fun foo(): jet.Unit in final class B : A, Z implements fun foo(): jet.Unit in trait Z.
|
||||
@@ -0,0 +1,15 @@
|
||||
open class A {
|
||||
open fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
trait Z {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
class B: A, Z {
|
||||
override fun foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
open class A {
|
||||
}
|
||||
|
||||
trait Z {
|
||||
fun foo()
|
||||
}
|
||||
|
||||
class B: A, Z {
|
||||
override fun foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
open class A {
|
||||
open fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class B: A {
|
||||
fun bar() {
|
||||
foo()
|
||||
}
|
||||
|
||||
override fun foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
open class A {
|
||||
}
|
||||
|
||||
class B: A {
|
||||
fun bar() {
|
||||
foo()
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
interface A {
|
||||
void foo();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class B: A {
|
||||
override fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
fun foo(): jet.Unit in final class B : A implements [Java] void foo() in interface A.
|
||||
@@ -0,0 +1,5 @@
|
||||
class B implements A {
|
||||
public void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
class B implements A {
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
trait A {
|
||||
fun <caret>foo()
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
trait A {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
interface A {
|
||||
void foo();
|
||||
}
|
||||
|
||||
interface Z {
|
||||
void foo();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class B: A, Z {
|
||||
public override fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fun foo(): jet.Unit in final class B : A, Z implements [Java] void foo() in interface A.
|
||||
fun foo(): jet.Unit in final class B : A, Z implements [Java] void foo() in interface Z.
|
||||
@@ -0,0 +1,5 @@
|
||||
class B implements A, Z {
|
||||
public void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class B implements A, Z {
|
||||
public void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
trait A {
|
||||
fun <caret>foo()
|
||||
}
|
||||
|
||||
trait Z {
|
||||
fun foo()
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
trait A {
|
||||
}
|
||||
|
||||
trait Z {
|
||||
fun foo()
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class A {
|
||||
void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class A {
|
||||
void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class B: A {
|
||||
override fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
class B: A {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class B extends A {
|
||||
@Override
|
||||
void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
class B extends A {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
open class A {
|
||||
open fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
open class A {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class B extends A {
|
||||
void bar() {
|
||||
foo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class B extends A {
|
||||
void bar() {
|
||||
foo();
|
||||
}
|
||||
|
||||
public void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
open class A {
|
||||
open fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
open class A {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
public void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
interface Z {
|
||||
void foo();
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class B: A, Z {
|
||||
public override fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
fun foo(): jet.Unit in final class B : A, Z implements [Java] void foo() in interface Z.
|
||||
@@ -0,0 +1,5 @@
|
||||
class B extends A implements Z {
|
||||
public void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class B extends A implements Z {
|
||||
public void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class A {
|
||||
public fun <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
trait Z {
|
||||
fun foo()
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
class A {
|
||||
}
|
||||
|
||||
trait Z {
|
||||
fun foo()
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
interface A {
|
||||
public void <caret>foo();
|
||||
}
|
||||
|
||||
abstract class C implements B {
|
||||
@Override
|
||||
public void foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
interface A {
|
||||
}
|
||||
|
||||
abstract class C implements B {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
trait B: A {
|
||||
public override fun foo() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
|
||||
class D: C() {
|
||||
public override fun foo() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
trait B: A {
|
||||
}
|
||||
|
||||
class D: C() {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
interface A {
|
||||
public void foo();
|
||||
}
|
||||
|
||||
abstract class C implements B {
|
||||
@Override
|
||||
public void <caret>foo() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
interface A {
|
||||
public void foo();
|
||||
}
|
||||
|
||||
abstract class C implements B {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
trait B: A {
|
||||
public override fun foo() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
|
||||
class D: C() {
|
||||
public override fun foo() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
trait B: A {
|
||||
public override fun foo() {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
|
||||
class D: C() {
|
||||
}
|
||||
@@ -16,44 +16,99 @@
|
||||
|
||||
package org.jetbrains.jet.safeDelete;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.safeDelete.SafeDeleteHandler;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetClass;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetNamedFunction;
|
||||
import org.jetbrains.jet.lang.psi.JetObjectDeclarationName;
|
||||
import org.jetbrains.jet.plugin.JetLightProjectDescriptor;
|
||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractJetSafeDeleteTest extends LightCodeInsightTestCase {
|
||||
public abstract class AbstractJetSafeDeleteTest extends LightCodeInsightFixtureTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JetLightProjectDescriptor.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
String pathBase = PluginTestCaseBase.getTestDataPathBase();
|
||||
myFixture.setTestDataPath(pathBase.substring(0, pathBase.lastIndexOf("/idea/testData")));
|
||||
}
|
||||
|
||||
public void doClassTest(@NotNull String path) throws Exception {
|
||||
doTest(path, JetClass.class);
|
||||
doTest(path, JetClass.class, false);
|
||||
}
|
||||
|
||||
public void doObjectTest(@NotNull String path) throws Exception {
|
||||
doTest(path, JetObjectDeclarationName.class);
|
||||
doTest(path, JetObjectDeclarationName.class, false);
|
||||
}
|
||||
|
||||
private <T extends JetElement> void doTest(@NotNull String path, @NotNull Class<T> elementClass) throws Exception {
|
||||
configureByFile(path);
|
||||
public void doFunctionTest(@NotNull String path) throws Exception {
|
||||
doTest(path, JetNamedFunction.class, false);
|
||||
}
|
||||
|
||||
DataContext dataContext = getCurrentEditorDataContext();
|
||||
PsiElement element = PsiTreeUtil.getParentOfType(LangDataKeys.PSI_ELEMENT.getData(dataContext), elementClass, false);
|
||||
public void doFunctionTestWithJava(@NotNull String path) throws Exception {
|
||||
doTest(path, JetNamedFunction.class, true);
|
||||
}
|
||||
|
||||
public void doJavaMethodTest(@NotNull String path) throws Exception {
|
||||
doTest(path, PsiMethod.class, true);
|
||||
}
|
||||
|
||||
private <T extends PsiElement> void doTest(
|
||||
@NotNull String path, @NotNull Class<T> elementClass, boolean withJava) throws Exception {
|
||||
String[] filePaths;
|
||||
if (withJava) {
|
||||
filePaths = new String[]{path, path.endsWith(".java") ? path.replace(".java", ".kt") : path.replace(".kt", ".java")};
|
||||
}
|
||||
else {
|
||||
filePaths = new String[]{path};
|
||||
}
|
||||
|
||||
Editor[] editors = new Editor[filePaths.length];
|
||||
int i = 0;
|
||||
for (String filePath : filePaths) {
|
||||
myFixture.configureByFile(filePath);
|
||||
editors[i++] = myFixture.getEditor();
|
||||
}
|
||||
|
||||
PsiElement elementAtCaret = null;
|
||||
for (Editor editor : editors) {
|
||||
elementAtCaret = TargetElementUtilBase.findTargetElement(
|
||||
editor, TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED | TargetElementUtilBase.ELEMENT_NAME_ACCEPTED
|
||||
);
|
||||
if (elementAtCaret != null) break;
|
||||
}
|
||||
|
||||
assertNotNull("Couldn't find element at caret position", elementAtCaret);
|
||||
|
||||
T element = PsiTreeUtil.getParentOfType(elementAtCaret, elementClass, false);
|
||||
|
||||
try {
|
||||
new SafeDeleteHandler().invoke(getProject(), new PsiElement[] {element}, dataContext);
|
||||
checkResultByFile(path + ".after");
|
||||
SafeDeleteHandler.invoke(getProject(), new PsiElement[] {element}, null, true, null);
|
||||
for (int j = 0; j < filePaths.length; j++) {
|
||||
String expectedText = FileUtil.loadFile(new File(filePaths[j] + ".after"));
|
||||
assertEquals(StringUtil.convertLineSeparators(expectedText), editors[j].getDocument().getText());
|
||||
}
|
||||
}
|
||||
catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
|
||||
List<String> messages = new ArrayList<String>(e.getMessages());
|
||||
@@ -64,10 +119,4 @@ public abstract class AbstractJetSafeDeleteTest extends LightCodeInsightTestCase
|
||||
assertEquals(expectedMessage, StringUtil.join(messages, "\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.jet.safeDelete.AbstractJetSafeDeleteTest;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@InnerTestClasses({JetSafeDeleteTestGenerated.DeleteClass.class, JetSafeDeleteTestGenerated.DeleteObject.class})
|
||||
@InnerTestClasses({JetSafeDeleteTestGenerated.DeleteClass.class, JetSafeDeleteTestGenerated.DeleteObject.class, JetSafeDeleteTestGenerated.DeleteFunction.class, JetSafeDeleteTestGenerated.DeleteFunctionWithJavaUsages.class, JetSafeDeleteTestGenerated.DeleteJavaMethod.class})
|
||||
public class JetSafeDeleteTestGenerated extends AbstractJetSafeDeleteTest {
|
||||
@TestMetadata("idea/testData/safeDelete/deleteClass")
|
||||
public static class DeleteClass extends AbstractJetSafeDeleteTest {
|
||||
@@ -118,10 +118,142 @@ public class JetSafeDeleteTestGenerated extends AbstractJetSafeDeleteTest {
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/safeDelete/deleteFunction")
|
||||
public static class DeleteFunction extends AbstractJetSafeDeleteTest {
|
||||
public void testAllFilesPresentInDeleteFunction() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/safeDelete/deleteFunction"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("fun1.kt")
|
||||
public void testFun1() throws Exception {
|
||||
doFunctionTest("idea/testData/safeDelete/deleteFunction/fun1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("fun2.kt")
|
||||
public void testFun2() throws Exception {
|
||||
doFunctionTest("idea/testData/safeDelete/deleteFunction/fun2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implement1.kt")
|
||||
public void testImplement1() throws Exception {
|
||||
doFunctionTest("idea/testData/safeDelete/deleteFunction/implement1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implement2.kt")
|
||||
public void testImplement2() throws Exception {
|
||||
doFunctionTest("idea/testData/safeDelete/deleteFunction/implement2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noUsages.kt")
|
||||
public void testNoUsages() throws Exception {
|
||||
doFunctionTest("idea/testData/safeDelete/deleteFunction/noUsages.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("override1.kt")
|
||||
public void testOverride1() throws Exception {
|
||||
doFunctionTest("idea/testData/safeDelete/deleteFunction/override1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("override2.kt")
|
||||
public void testOverride2() throws Exception {
|
||||
doFunctionTest("idea/testData/safeDelete/deleteFunction/override2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overrideAndImplement1.kt")
|
||||
public void testOverrideAndImplement1() throws Exception {
|
||||
doFunctionTest("idea/testData/safeDelete/deleteFunction/overrideAndImplement1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overrideAndImplement2.kt")
|
||||
public void testOverrideAndImplement2() throws Exception {
|
||||
doFunctionTest("idea/testData/safeDelete/deleteFunction/overrideAndImplement2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overrideWithUsages.kt")
|
||||
public void testOverrideWithUsages() throws Exception {
|
||||
doFunctionTest("idea/testData/safeDelete/deleteFunction/overrideWithUsages.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/safeDelete/deleteFunctionWithJavaUsages")
|
||||
public static class DeleteFunctionWithJavaUsages extends AbstractJetSafeDeleteTest {
|
||||
public void testAllFilesPresentInDeleteFunctionWithJavaUsages() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/safeDelete/deleteFunctionWithJavaUsages"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("implement1.kt")
|
||||
public void testImplement1() throws Exception {
|
||||
doFunctionTestWithJava("idea/testData/safeDelete/deleteFunctionWithJavaUsages/implement1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implement2.kt")
|
||||
public void testImplement2() throws Exception {
|
||||
doFunctionTestWithJava("idea/testData/safeDelete/deleteFunctionWithJavaUsages/implement2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implement3.kt")
|
||||
public void testImplement3() throws Exception {
|
||||
doFunctionTestWithJava("idea/testData/safeDelete/deleteFunctionWithJavaUsages/implement3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implement4.kt")
|
||||
public void testImplement4() throws Exception {
|
||||
doFunctionTestWithJava("idea/testData/safeDelete/deleteFunctionWithJavaUsages/implement4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("override1.kt")
|
||||
public void testOverride1() throws Exception {
|
||||
doFunctionTestWithJava("idea/testData/safeDelete/deleteFunctionWithJavaUsages/override1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("override2.kt")
|
||||
public void testOverride2() throws Exception {
|
||||
doFunctionTestWithJava("idea/testData/safeDelete/deleteFunctionWithJavaUsages/override2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("override3.kt")
|
||||
public void testOverride3() throws Exception {
|
||||
doFunctionTestWithJava("idea/testData/safeDelete/deleteFunctionWithJavaUsages/override3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overrideAndImplement1.kt")
|
||||
public void testOverrideAndImplement1() throws Exception {
|
||||
doFunctionTestWithJava("idea/testData/safeDelete/deleteFunctionWithJavaUsages/overrideAndImplement1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overrideAndImplement2.kt")
|
||||
public void testOverrideAndImplement2() throws Exception {
|
||||
doFunctionTestWithJava("idea/testData/safeDelete/deleteFunctionWithJavaUsages/overrideAndImplement2.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/safeDelete/deleteJavaMethod")
|
||||
public static class DeleteJavaMethod extends AbstractJetSafeDeleteTest {
|
||||
public void testAllFilesPresentInDeleteJavaMethod() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/safeDelete/deleteJavaMethod"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("mixedHierarchy1.kt")
|
||||
public void testMixedHierarchy1() throws Exception {
|
||||
doJavaMethodTest("idea/testData/safeDelete/deleteJavaMethod/mixedHierarchy1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("mixedHierarchy2.kt")
|
||||
public void testMixedHierarchy2() throws Exception {
|
||||
doJavaMethodTest("idea/testData/safeDelete/deleteJavaMethod/mixedHierarchy2.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite("JetSafeDeleteTestGenerated");
|
||||
suite.addTestSuite(DeleteClass.class);
|
||||
suite.addTestSuite(DeleteObject.class);
|
||||
suite.addTestSuite(DeleteFunction.class);
|
||||
suite.addTestSuite(DeleteFunctionWithJavaUsages.class);
|
||||
suite.addTestSuite(DeleteJavaMethod.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user