Added more quickfixes; added tests
This commit is contained in:
@@ -90,13 +90,15 @@ public class JetPsiChecker implements Annotator {
|
||||
DiagnosticWithPsiElement diagnosticWithPsiElement = (DiagnosticWithPsiElement) diagnostic;
|
||||
if (diagnostic.getFactory() instanceof PsiElementOnlyDiagnosticFactory) {
|
||||
PsiElementOnlyDiagnosticFactory factory = (PsiElementOnlyDiagnosticFactory) diagnostic.getFactory();
|
||||
IntentionActionFactory intentionActionFactory = QuickFixes.get(factory);
|
||||
IntentionAction action = null;
|
||||
if (intentionActionFactory != null) {
|
||||
action = intentionActionFactory.createAction(diagnosticWithPsiElement);
|
||||
}
|
||||
if (action != null) {
|
||||
annotation.registerFix(action);
|
||||
Set<IntentionActionFactory> intentionActionFactories = QuickFixes.get(factory);
|
||||
for (IntentionActionFactory intentionActionFactory : intentionActionFactories) {
|
||||
IntentionAction action = null;
|
||||
if (intentionActionFactory != null) {
|
||||
action = intentionActionFactory.createAction(diagnosticWithPsiElement);
|
||||
}
|
||||
if (action != null) {
|
||||
annotation.registerFix(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class AddFunctionBodyFix extends IntentionActionForPsiElement<JetFunctionOrPropertyAccessor> {
|
||||
public AddFunctionBodyFix(@NotNull JetFunctionOrPropertyAccessor element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Add function body";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Add function body";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return super.isAvailable(project, editor, file) &&
|
||||
element.getBodyExpression() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetFunctionOrPropertyAccessor newElement = (JetFunctionOrPropertyAccessor) element.copy();
|
||||
JetExpression bodyExpression = newElement.getBodyExpression();
|
||||
if (!(newElement.getLastChild() instanceof PsiWhiteSpace)) {
|
||||
newElement.add(JetPsiFactory.createWhiteSpace(project));
|
||||
}
|
||||
if (bodyExpression == null) {
|
||||
newElement.add(JetPsiFactory.createEmptyBody(project));
|
||||
}
|
||||
element.replace(newElement);
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetFunctionOrPropertyAccessor> createFactory() {
|
||||
return new IntentionActionFactory<JetFunctionOrPropertyAccessor>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<JetFunctionOrPropertyAccessor> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetFunctionOrPropertyAccessor;
|
||||
return new AddFunctionBodyFix((JetFunctionOrPropertyAccessor) diagnostic.getPsiElement());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,9 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -17,27 +19,41 @@ import org.jetbrains.jet.lexer.JetTokens;
|
||||
*/
|
||||
public class AddModifierFix extends ModifierFix {
|
||||
private final JetToken[] modifiersThanCanBeReplaced;
|
||||
private final JetToken[] conflictedModifiers;
|
||||
|
||||
private AddModifierFix(@NotNull JetModifierListOwner element, JetKeywordToken modifier, JetToken[] modifiersThanCanBeReplaced) {
|
||||
private AddModifierFix(@NotNull JetModifierListOwner element, JetKeywordToken modifier, JetToken[] modifiersThanCanBeReplaced, JetToken[] conflictedModifiers) {
|
||||
super(element, modifier);
|
||||
this.modifiersThanCanBeReplaced = modifiersThanCanBeReplaced;
|
||||
this.conflictedModifiers = conflictedModifiers;
|
||||
}
|
||||
|
||||
|
||||
private static boolean checkConflictModifiers(JetModifierListOwner element, JetToken[] conflictedModifiers) {
|
||||
for (JetToken conflictedModifier : conflictedModifiers) {
|
||||
if (element.hasModifier(conflictedModifier)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "add." + modifier.getValue() + ".modifier.fix";
|
||||
if (modifier == JetTokens.ABSTRACT_KEYWORD) {
|
||||
return "Make " + getElementName() + " " + modifier.getValue();
|
||||
}
|
||||
return "Add '" + modifier.getValue() + "' modifier";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "add." + modifier.getValue() + ".modifier.family";
|
||||
return "Add modifier";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return super.isAvailable(project, editor, file) && !element.hasModifier(JetTokens.FINAL_KEYWORD);
|
||||
return element.isValid() && !checkConflictModifiers(element, conflictedModifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,17 +97,17 @@ public class AddModifierFix extends ModifierFix {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetModifierListOwner> createFactory(final JetKeywordToken modifier, final JetToken[] modifiersThatCanBeReplaced) {
|
||||
public static IntentionActionFactory<JetModifierListOwner> createFactory(final JetKeywordToken modifier, final JetToken[] modifiersThatCanBeReplaced, final JetToken[] conflictedModifiers) {
|
||||
return new IntentionActionFactory<JetModifierListOwner>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<JetModifierListOwner> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetModifierListOwner;
|
||||
return new AddModifierFix((JetModifierListOwner) diagnostic.getPsiElement(), modifier, modifiersThatCanBeReplaced);
|
||||
return new AddModifierFix((JetModifierListOwner) diagnostic.getPsiElement(), modifier, modifiersThatCanBeReplaced, conflictedModifiers);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetModifierListOwner> createFactory(final JetKeywordToken modifier) {
|
||||
return createFactory(modifier, new JetToken[] {});
|
||||
return createFactory(modifier, new JetToken[0], new JetToken[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithAdditionalInfo;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.JetParameter;
|
||||
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lang.psi.JetTypeReference;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class ChangeAccessorTypeFix extends IntentionActionForPsiElement<JetPropertyAccessor> {
|
||||
private final JetType type;
|
||||
|
||||
public ChangeAccessorTypeFix(@NotNull JetPropertyAccessor element, JetType type) {
|
||||
super(element);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return (element.isGetter() ? "Change getter " : "Change setter parameter ") + "type to " + type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Change accessor type";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetPropertyAccessor newElement = (JetPropertyAccessor) element.copy();
|
||||
JetTypeReference newTypeReference = JetPsiFactory.createType(project, type.toString());
|
||||
|
||||
if (element.isGetter()) {
|
||||
JetTypeReference returnTypeReference = newElement.getReturnTypeReference();
|
||||
assert returnTypeReference != null;
|
||||
CodeEditUtil.replaceChild(newElement.getNode(), returnTypeReference.getNode(), newTypeReference.getNode());
|
||||
element.replace(newElement);
|
||||
}
|
||||
else {
|
||||
JetParameter parameter = newElement.getParameter();
|
||||
assert parameter != null;
|
||||
JetTypeReference typeReference = parameter.getTypeReference();
|
||||
assert typeReference != null;
|
||||
CodeEditUtil.replaceChild(parameter.getNode(), typeReference.getNode(), newTypeReference.getNode());
|
||||
element.replace(newElement);
|
||||
}
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetPropertyAccessor> createFactory() {
|
||||
return new IntentionActionFactory<JetPropertyAccessor>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<JetPropertyAccessor> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic instanceof DiagnosticWithAdditionalInfo;
|
||||
assert diagnostic.getPsiElement() instanceof JetPropertyAccessor;
|
||||
assert ((DiagnosticWithAdditionalInfo) diagnostic).getInfo() instanceof JetType;
|
||||
return new ChangeAccessorTypeFix((JetPropertyAccessor) diagnostic.getPsiElement(), (JetType) ((DiagnosticWithAdditionalInfo) diagnostic).getInfo());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class ChangeVariableMutabilityFix extends IntentionActionForPsiElement<JetProperty> {
|
||||
public ChangeVariableMutabilityFix(@NotNull JetProperty element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Make variable " + (element.isVar() ? "immutable" : "mutable");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Change variable mutability";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetProperty newElement = (JetProperty) element.copy();
|
||||
if (newElement.isVar()) {
|
||||
PsiElement varElement = newElement.getNode().findChildByType(JetTokens.VAR_KEYWORD).getPsi();
|
||||
|
||||
JetProperty valProperty = JetPsiFactory.createProperty(project, "x", "Any", false);
|
||||
PsiElement valElement = valProperty.getNode().findChildByType(JetTokens.VAL_KEYWORD).getPsi();
|
||||
CodeEditUtil.replaceChild(newElement.getNode(), varElement.getNode(), valElement.getNode());
|
||||
}
|
||||
else {
|
||||
PsiElement valElement = newElement.getNode().findChildByType(JetTokens.VAL_KEYWORD).getPsi();
|
||||
|
||||
JetProperty varProperty = JetPsiFactory.createProperty(project, "x", "Any", true);
|
||||
PsiElement varElement = varProperty.getNode().findChildByType(JetTokens.VAR_KEYWORD).getPsi();
|
||||
CodeEditUtil.replaceChild(newElement.getNode(), valElement.getNode(), varElement.getNode());
|
||||
}
|
||||
element.replace(newElement);
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetProperty> createFactory() {
|
||||
return new IntentionActionFactory<JetProperty>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<JetProperty> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetProperty;
|
||||
return new ChangeVariableMutabilityFix((JetProperty) diagnostic.getPsiElement());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,6 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
*/
|
||||
public interface IntentionActionFactory<T extends PsiElement> {
|
||||
|
||||
IntentionActionForPsiElement createAction(DiagnosticWithPsiElement diagnostic);
|
||||
IntentionActionForPsiElement<T> createAction(DiagnosticWithPsiElement diagnostic);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -13,4 +16,14 @@ public abstract class IntentionActionForPsiElement<T extends PsiElement> impleme
|
||||
public IntentionActionForPsiElement(@NotNull T element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return element.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
@@ -18,14 +17,14 @@ public abstract class ModifierFix extends IntentionActionForPsiElement<JetModifi
|
||||
this.modifier = modifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return element.isValid();
|
||||
@NotNull
|
||||
protected String getElementName() {
|
||||
if (element instanceof PsiNameIdentifierOwner) {
|
||||
PsiElement nameIdentifier = ((PsiNameIdentifierOwner) element).getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
return "'" + nameIdentifier.getText() + "'";
|
||||
}
|
||||
}
|
||||
return "'" + element.getText() + "'";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithAdditionalInfo;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElementImpl;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class QuickFixUtil {
|
||||
private QuickFixUtil() {}
|
||||
|
||||
public static <T extends PsiElement> IntentionActionFactory<T> createFactoryRedirectingAdditionalInfoToAnotherFactory(final IntentionActionFactory<T> factory) {
|
||||
return new IntentionActionFactory<T>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<T> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
//no type check; should be followed manually
|
||||
assert diagnostic instanceof DiagnosticWithAdditionalInfo;
|
||||
Object info = ((DiagnosticWithAdditionalInfo) diagnostic).getInfo();
|
||||
T element = null;
|
||||
try {
|
||||
element = (T) info;
|
||||
}
|
||||
catch (ClassCastException ex) {
|
||||
assert false : ex;
|
||||
}
|
||||
return factory.createAction(new DiagnosticWithPsiElementImpl<T>(diagnostic.getFactory(), diagnostic.getSeverity(), diagnostic.getMessage(), element));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,39 +1,88 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.diagnostics.PsiElementOnlyDiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.psi.JetFunctionOrPropertyAccessor;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
||||
import org.jetbrains.jet.lang.psi.JetPropertyAccessor;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class QuickFixes {
|
||||
private static Map<PsiElementOnlyDiagnosticFactory, IntentionActionFactory> actionMap = Maps.newHashMap();
|
||||
private static HashMultimap<PsiElementOnlyDiagnosticFactory, IntentionActionFactory> actionMap = HashMultimap.create();
|
||||
|
||||
public static IntentionActionFactory get(PsiElementOnlyDiagnosticFactory diagnosticFactory) {
|
||||
public static Set<IntentionActionFactory> get(PsiElementOnlyDiagnosticFactory diagnosticFactory) {
|
||||
return actionMap.get(diagnosticFactory);
|
||||
}
|
||||
|
||||
private QuickFixes() {}
|
||||
|
||||
private static <T extends PsiElement> void add(PsiElementOnlyDiagnosticFactory<T> diagnosticFactory, IntentionActionFactory<T> actionFactory) {
|
||||
private static <T extends PsiElement> void add(PsiElementOnlyDiagnosticFactory<? extends T> diagnosticFactory, IntentionActionFactory<T> actionFactory) {
|
||||
actionMap.put(diagnosticFactory, actionFactory);
|
||||
}
|
||||
|
||||
|
||||
static {
|
||||
IntentionActionFactory<JetModifierListOwner> removeAbstractModifierFactory = RemoveModifierFix.createFactory(JetTokens.ABSTRACT_KEYWORD);
|
||||
IntentionActionFactory<JetModifierListOwner> addAbstractModifierFactory = AddModifierFix.createFactory(JetTokens.ABSTRACT_KEYWORD, new JetToken[]{JetTokens.OPEN_KEYWORD});
|
||||
IntentionActionFactory<JetModifierListOwner> addAbstractModifierFactory = AddModifierFix.createFactory(JetTokens.ABSTRACT_KEYWORD, new JetToken[]{JetTokens.OPEN_KEYWORD}, new JetToken[] {JetTokens.FINAL_KEYWORD});
|
||||
|
||||
add(Errors.ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS, removeAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_PROPERTY_NOT_IN_CLASS, removeAbstractModifierFactory);
|
||||
|
||||
IntentionActionFactory<JetProperty> removePartsFromPropertyFactory = RemovePartsFromPropertyFix.createFactory();
|
||||
add(Errors.ABSTRACT_PROPERTY_WITH_INITIALIZER, removeAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_PROPERTY_WITH_INITIALIZER, removePartsFromPropertyFactory);
|
||||
|
||||
add(Errors.ABSTRACT_PROPERTY_WITH_GETTER, removeAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_PROPERTY_WITH_GETTER, removePartsFromPropertyFactory);
|
||||
|
||||
add(Errors.ABSTRACT_PROPERTY_WITH_SETTER, removeAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_PROPERTY_WITH_SETTER, removePartsFromPropertyFactory);
|
||||
|
||||
add(Errors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT, addAbstractModifierFactory);
|
||||
add(Errors.REDUNDANT_ABSTRACT, removeAbstractModifierFactory);
|
||||
|
||||
IntentionActionFactory<JetModifierListOwner> addAbstractToClassFactory = QuickFixUtil.createFactoryRedirectingAdditionalInfoToAnotherFactory(addAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, removeAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, addAbstractToClassFactory);
|
||||
|
||||
IntentionActionFactory<JetFunctionOrPropertyAccessor> removeFunctionBodyFactory = RemoveFunctionBodyFix.createFactory();
|
||||
add(Errors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, removeAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, addAbstractToClassFactory);
|
||||
|
||||
add(Errors.ABSTRACT_FUNCTION_WITH_BODY, removeAbstractModifierFactory);
|
||||
add(Errors.ABSTRACT_FUNCTION_WITH_BODY, removeFunctionBodyFactory);
|
||||
|
||||
IntentionActionFactory<JetFunctionOrPropertyAccessor> addFunctionBodyFactory = AddFunctionBodyFix.createFactory();
|
||||
add(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, addAbstractModifierFactory);
|
||||
add(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, addFunctionBodyFactory);
|
||||
|
||||
add(Errors.NON_MEMBER_ABSTRACT_FUNCTION, removeAbstractModifierFactory);
|
||||
add(Errors.NON_MEMBER_ABSTRACT_ACCESSOR, removeAbstractModifierFactory);
|
||||
add(Errors.NON_MEMBER_FUNCTION_NO_BODY, addFunctionBodyFactory);
|
||||
|
||||
add(Errors.NOTHING_TO_OVERRIDE, RemoveModifierFix.createFactory(JetTokens.OVERRIDE_KEYWORD));
|
||||
add(Errors.VIRTUAL_METHOD_HIDDEN, AddModifierFix.createFactory(JetTokens.OVERRIDE_KEYWORD));
|
||||
|
||||
add(Errors.VAL_WITH_SETTER, ChangeVariableMutabilityFix.createFactory());
|
||||
|
||||
add(Errors.USELESS_CAST_STATIC_ASSERT_IS_FINE, ReplaceOperationInBinaryExpressionFix.createChangeCastToStaticAssertFactory());
|
||||
add(Errors.USELESS_CAST, RemoveRightPartOfBinaryExpressionFix.createRemoveCastFactory());
|
||||
|
||||
IntentionActionFactory<JetPropertyAccessor> changeAccessorTypeFactory = ChangeAccessorTypeFix.createFactory();
|
||||
add(Errors.WRONG_SETTER_PARAMETER_TYPE, changeAccessorTypeFactory);
|
||||
add(Errors.WRONG_GETTER_RETURN_TYPE, changeAccessorTypeFactory);
|
||||
|
||||
add(Errors.USELESS_ELVIS, RemoveRightPartOfBinaryExpressionFix.createRemoveElvisOperatorFactory());
|
||||
|
||||
add(Errors.UNNECESSARY_SAFE_CALL, ReplaceSafeCallToDotCall.createFactory());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class RemoveFunctionBodyFix extends IntentionActionForPsiElement<JetFunctionOrPropertyAccessor> {
|
||||
|
||||
public RemoveFunctionBodyFix(@NotNull JetFunctionOrPropertyAccessor element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Remove function body";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Remove function body";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return super.isAvailable(project, editor, file) &&
|
||||
element.getBodyExpression() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetFunctionOrPropertyAccessor newElement = (JetFunctionOrPropertyAccessor) element.copy();
|
||||
JetExpression bodyExpression = newElement.getBodyExpression();
|
||||
if (bodyExpression != null) {
|
||||
PsiElement prevSibling = bodyExpression.getPrevSibling();
|
||||
if (prevSibling instanceof PsiWhiteSpace) {
|
||||
((JetElement)newElement).deleteChildInternal(prevSibling.getNode());
|
||||
}
|
||||
((JetElement)newElement).deleteChildInternal(bodyExpression.getNode());
|
||||
}
|
||||
element.replace(newElement);
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetFunctionOrPropertyAccessor> createFactory() {
|
||||
return new IntentionActionFactory<JetFunctionOrPropertyAccessor>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<JetFunctionOrPropertyAccessor> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetFunctionOrPropertyAccessor;
|
||||
return new RemoveFunctionBodyFix((JetFunctionOrPropertyAccessor) diagnostic.getPsiElement());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,16 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
@@ -25,13 +28,21 @@ public class RemoveModifierFix extends ModifierFix {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "remove." + modifier.getValue() + ".modifier.fix";
|
||||
if (modifier == JetTokens.ABSTRACT_KEYWORD) {
|
||||
return "Make " + getElementName() + " not " + modifier.getValue();
|
||||
}
|
||||
return "Remove '" + modifier.getValue() + "' modifier";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "remove." + modifier.getValue() + "abstract.modifier.family";
|
||||
return "Remove modifier";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return element.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,14 +51,29 @@ public class RemoveModifierFix extends ModifierFix {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static JetModifierListOwner removeModifier(PsiElement element, JetToken modifier) {
|
||||
JetModifierListOwner newElement = (JetModifierListOwner) (element.copy());
|
||||
/*package*/ static <T extends JetModifierListOwner> T removeModifier(T element, JetToken modifier) {
|
||||
T newElement = (T) (element.copy());
|
||||
assert newElement.hasModifier(modifier);
|
||||
ASTNode modifierNode = newElement.getModifierList().getModifierNode(modifier);
|
||||
JetModifierList modifierList = newElement.getModifierList();
|
||||
ASTNode modifierNode = modifierList.getModifierNode(modifier);
|
||||
PsiElement whiteSpace = modifierNode.getPsi().getNextSibling();
|
||||
((JetElement)newElement).deleteChildInternal(modifierNode);
|
||||
if (modifierList.getChildren().length == 0) {
|
||||
whiteSpace = modifierList.getNextSibling();
|
||||
((JetElement) newElement).deleteChildInternal(modifierList.getNode());
|
||||
removeWhiteSpace(newElement, whiteSpace);
|
||||
}
|
||||
else {
|
||||
removeWhiteSpace(newElement, whiteSpace);
|
||||
}
|
||||
return newElement;
|
||||
}
|
||||
|
||||
private static void removeWhiteSpace(PsiElement element, PsiElement subElement) {
|
||||
if (subElement instanceof PsiWhiteSpace) {
|
||||
((JetElement) element).deleteChildInternal(subElement.getNode());
|
||||
}
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetModifierListOwner> createFactory(final JetKeywordToken modifier) {
|
||||
return new IntentionActionFactory<JetModifierListOwner>() {
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithAdditionalInfo;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class RemovePartsFromPropertyFix extends IntentionActionForPsiElement<JetProperty> {
|
||||
private final JetType type;
|
||||
private final String partsToRemove;
|
||||
|
||||
private RemovePartsFromPropertyFix(@NotNull JetProperty element, JetType type) {
|
||||
super(element);
|
||||
this.type = type;
|
||||
partsToRemove = partsToRemove(element.getGetter() != null && element.getGetter().getBodyExpression() != null,
|
||||
element.getSetter() != null && element.getSetter().getBodyExpression() != null,
|
||||
element.getInitializer() != null);
|
||||
}
|
||||
|
||||
private static String partsToRemove(boolean hasGetter, boolean hasSetter, boolean hasInitializer) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (hasGetter) {
|
||||
sb.append("getter");
|
||||
if (hasSetter && hasInitializer) {
|
||||
sb.append(", ");
|
||||
}
|
||||
else if (hasSetter || hasInitializer) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
}
|
||||
if (hasSetter) {
|
||||
sb.append("setter");
|
||||
if (hasInitializer) {
|
||||
sb.append(" and ");
|
||||
}
|
||||
}
|
||||
if (hasInitializer) {
|
||||
sb.append("initializer");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Remove " + partsToRemove + " from property";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Remove parts from property to make it abstract";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return element.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
JetProperty newElement = (JetProperty) element.copy();
|
||||
JetPropertyAccessor getter = newElement.getGetter();
|
||||
if (getter != null) {
|
||||
newElement.deleteChildInternal(getter.getNode());
|
||||
}
|
||||
JetPropertyAccessor setter = newElement.getSetter();
|
||||
if (setter != null) {
|
||||
newElement.deleteChildInternal(setter.getNode());
|
||||
}
|
||||
JetExpression initializer = newElement.getInitializer();
|
||||
if (initializer != null) {
|
||||
PsiElement nameIdentifier = newElement.getNameIdentifier();
|
||||
assert nameIdentifier != null;
|
||||
PsiElement nextSibling = nameIdentifier.getNextSibling();
|
||||
assert nextSibling != null;
|
||||
newElement.deleteChildRange(nextSibling, initializer);
|
||||
|
||||
if (newElement.getPropertyTypeRef() == null) {
|
||||
newElement = addPropertyType(project, newElement, type);
|
||||
}
|
||||
}
|
||||
element.replace(newElement);
|
||||
}
|
||||
|
||||
public static JetProperty addPropertyType(Project project, JetProperty property, JetType type) {
|
||||
JetProperty newProperty = (JetProperty) property.copy();
|
||||
JetTypeReference typeReference = JetPsiFactory.createType(project, type.toString());
|
||||
PsiElement[] colon = JetPsiFactory.createColon(project);
|
||||
PsiElement nameIdentifier = newProperty.getNameIdentifier();
|
||||
assert nameIdentifier != null;
|
||||
newProperty.addAfter(typeReference, nameIdentifier);
|
||||
for (int i = colon.length - 1; i >= 0; i--) {
|
||||
newProperty.addAfter(colon[i], nameIdentifier);
|
||||
}
|
||||
return newProperty;
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetProperty> createFactory() {
|
||||
return new IntentionActionFactory<JetProperty>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<JetProperty> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetProperty;
|
||||
assert diagnostic instanceof DiagnosticWithAdditionalInfo;
|
||||
|
||||
Object info = ((DiagnosticWithAdditionalInfo) diagnostic).getInfo();
|
||||
assert info instanceof JetType;
|
||||
return new RemovePartsFromPropertyFix((JetProperty) diagnostic.getPsiElement(), (JetType) info);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpressionWithTypeRHS;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public abstract class RemoveRightPartOfBinaryExpressionFix<T extends JetExpression> extends IntentionActionForPsiElement<T> {
|
||||
public RemoveRightPartOfBinaryExpressionFix(@NotNull T element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Remove right part of a binary expression";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
if (element instanceof JetBinaryExpression) {
|
||||
JetBinaryExpression newElement = (JetBinaryExpression) element.copy();
|
||||
element.replace(newElement.getLeft());
|
||||
}
|
||||
else if (element instanceof JetBinaryExpressionWithTypeRHS) {
|
||||
JetBinaryExpressionWithTypeRHS newElement = (JetBinaryExpressionWithTypeRHS) element.copy();
|
||||
element.replace(newElement.getLeft());
|
||||
}
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetBinaryExpressionWithTypeRHS> createRemoveCastFactory() {
|
||||
return new IntentionActionFactory<JetBinaryExpressionWithTypeRHS>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<JetBinaryExpressionWithTypeRHS> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetBinaryExpressionWithTypeRHS;
|
||||
return new RemoveRightPartOfBinaryExpressionFix<JetBinaryExpressionWithTypeRHS>((JetBinaryExpressionWithTypeRHS) diagnostic.getPsiElement()) {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Remove cast";
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetBinaryExpression> createRemoveElvisOperatorFactory() {
|
||||
return new IntentionActionFactory<JetBinaryExpression>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<JetBinaryExpression> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetBinaryExpression;
|
||||
return new RemoveRightPartOfBinaryExpressionFix<JetBinaryExpression>((JetBinaryExpression) diagnostic.getPsiElement()) {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Remove elvis operator";
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.JetBinaryExpressionWithTypeRHS;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public abstract class ReplaceOperationInBinaryExpressionFix<T extends JetExpression> extends IntentionActionForPsiElement<T> {
|
||||
private final String expressionWithNecessaryOperation;
|
||||
public ReplaceOperationInBinaryExpressionFix(@NotNull T element, String expressionWithNecessaryOperation) {
|
||||
super(element);
|
||||
this.expressionWithNecessaryOperation = expressionWithNecessaryOperation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Replace operation in a binary expression";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
if (element instanceof JetBinaryExpressionWithTypeRHS) {
|
||||
JetBinaryExpressionWithTypeRHS expression = (JetBinaryExpressionWithTypeRHS) JetPsiFactory.createExpression(project, expressionWithNecessaryOperation);
|
||||
|
||||
JetBinaryExpressionWithTypeRHS newElement = (JetBinaryExpressionWithTypeRHS) element.copy();
|
||||
CodeEditUtil.replaceChild(newElement.getNode(), newElement.getOperationSign().getNode(), expression.getOperationSign().getNode());
|
||||
|
||||
element.replace(newElement);
|
||||
}
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetBinaryExpressionWithTypeRHS> createChangeCastToStaticAssertFactory() {
|
||||
return new IntentionActionFactory<JetBinaryExpressionWithTypeRHS>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<JetBinaryExpressionWithTypeRHS> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetBinaryExpressionWithTypeRHS;
|
||||
return new ReplaceOperationInBinaryExpressionFix<JetBinaryExpressionWithTypeRHS>((JetBinaryExpressionWithTypeRHS) diagnostic.getPsiElement(), "2 : Int") {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Replace a cast with a static assert";
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class ReplaceSafeCallToDotCall extends IntentionActionForPsiElement<JetElement> {
|
||||
|
||||
public ReplaceSafeCallToDotCall(@NotNull JetElement element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Replace to dot call";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Replace safe call to dot call";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
if (element instanceof JetSafeQualifiedExpression) {
|
||||
JetSafeQualifiedExpression safeQualifiedExpression = (JetSafeQualifiedExpression) element;
|
||||
JetDotQualifiedExpression newElement = (JetDotQualifiedExpression) JetPsiFactory.createExpression(project, "x.foo");
|
||||
|
||||
CodeEditUtil.replaceChild(newElement.getNode(), newElement.getSelectorExpression().getNode(), safeQualifiedExpression.getSelectorExpression().getNode());
|
||||
CodeEditUtil.replaceChild(newElement.getNode(), newElement.getReceiverExpression().getNode(), safeQualifiedExpression.getReceiverExpression().getNode());
|
||||
|
||||
element.replace(newElement);
|
||||
}
|
||||
else if (element instanceof JetWhenConditionCall) {
|
||||
JetWhenConditionCall newElement = (JetWhenConditionCall) element;
|
||||
JetDotQualifiedExpression callExpression = (JetDotQualifiedExpression) JetPsiFactory.createExpression(project, "x.foo");
|
||||
CodeEditUtil.replaceChild(newElement.getNode(), newElement.getOperationTokenNode(), callExpression.getOperationTokenNode());
|
||||
|
||||
element.replace(newElement);
|
||||
}
|
||||
}
|
||||
|
||||
public static IntentionActionFactory<JetElement> createFactory() {
|
||||
return new IntentionActionFactory<JetElement>() {
|
||||
@Override
|
||||
public IntentionActionForPsiElement<JetElement> createAction(DiagnosticWithPsiElement diagnostic) {
|
||||
assert diagnostic.getPsiElement() instanceof JetElement;
|
||||
return new ReplaceSafeCallToDotCall((JetElement) diagnostic.getPsiElement());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'foo' not abstract" "true"
|
||||
class A() {
|
||||
<caret>fun foo()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove function body" "true"
|
||||
abstract class A() {
|
||||
<caret>abstract fun foo()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'A' abstract" "true"
|
||||
abstract class A() {
|
||||
<caret>abstract var i : Int
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'i' not abstract" "true"
|
||||
class A() {
|
||||
<caret>var i : Int
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// "Make 'i' not abstract" "true"
|
||||
class A(<caret>val i: Int) {}
|
||||
@@ -0,0 +1,2 @@
|
||||
// "Make 'i' not abstract" "true"
|
||||
<caret>val i: Int = 1
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove initializer from property" "true"
|
||||
abstract class A {
|
||||
abstract var i : Int<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove initializer from property" "true"
|
||||
abstract class A {
|
||||
abstract var i : Int<caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Make 'i' not abstract" "true"
|
||||
class B {
|
||||
<caret>val i: Int
|
||||
get() = $i
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Remove getter and initializer from property" "true"
|
||||
abstract class B {
|
||||
abstract val i : <caret>Int
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'i' not abstract" "true"
|
||||
class A {
|
||||
<caret>var i = 0
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Make 'j' not abstract" "true"
|
||||
class B {
|
||||
<caret>var j: Int
|
||||
set(v: Int) {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'i' abstract" "true"
|
||||
abstract class A() {
|
||||
abstract var <caret>i : Int
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Add function body" "true"
|
||||
class A() {
|
||||
fun <caret>foo() {}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// "Make 'abstract get' not abstract" "true"
|
||||
val i : Int = 0; <caret>get
|
||||
@@ -0,0 +1,2 @@
|
||||
// "Make 'foo' not abstract" "true"
|
||||
<caret>fun foo()
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Add function body" "true"
|
||||
namespace a {
|
||||
fun <caret>foo() {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'foo' not abstract" "true"
|
||||
trait A {
|
||||
<caret>fun foo()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'foo' abstract" "true"
|
||||
abstract class B() {
|
||||
abstract fun <caret>foo()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'foo' not abstract" "true"
|
||||
class A() {
|
||||
<caret>abstract fun foo()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove function body" "true"
|
||||
abstract class A() {
|
||||
<caret>abstract fun foo() {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'A' abstract" "true"
|
||||
class A() {
|
||||
<caret>abstract var i : Int
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'i' not abstract" "true"
|
||||
class A() {
|
||||
<caret>abstract var i : Int
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
// "Make 'i' not abstract" "true"
|
||||
class A(<caret>abstract val i: Int) {}
|
||||
@@ -0,0 +1,2 @@
|
||||
// "Make 'i' not abstract" "true"
|
||||
<caret>abstract val i: Int = 1
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove initializer from property" "true"
|
||||
abstract class A {
|
||||
abstract var i = 0<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove initializer from property" "true"
|
||||
abstract class A {
|
||||
abstract var i : Int = 0<caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Make 'i' not abstract" "true"
|
||||
class B {
|
||||
<caret>abstract val i: Int
|
||||
get() = $i
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Remove getter and initializer from property" "true"
|
||||
abstract class B {
|
||||
abstract val i = <caret>0
|
||||
get() = $i
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'i' not abstract" "true"
|
||||
class A {
|
||||
<caret>abstract var i = 0
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Make 'j' not abstract" "true"
|
||||
class B {
|
||||
abstract<caret> var j: Int
|
||||
set(v: Int) {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'foo' abstract" "false"
|
||||
class B() {
|
||||
final fun <caret>foo()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'i' abstract" "true"
|
||||
abstract class A() {
|
||||
var <caret>i : Int
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Add function body" "true"
|
||||
class A() {
|
||||
fun <caret>foo()
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
// "Make 'abstract get' not abstract" "true"
|
||||
val i : Int = 0; <caret>abstract get
|
||||
@@ -0,0 +1,2 @@
|
||||
// "Make 'foo' not abstract" "true"
|
||||
<caret>abstract fun foo()
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Add function body" "true"
|
||||
namespace a {
|
||||
fun <caret>foo()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'foo' not abstract" "true"
|
||||
trait A {
|
||||
<caret>abstract fun foo()
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Make 'foo' abstract" "true"
|
||||
abstract class B() {
|
||||
open fun <caret>foo()
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Make variable mutable" "true"
|
||||
class A() {
|
||||
var a: Int = 0
|
||||
<caret>set(v: Int) {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Make variable mutable" "true"
|
||||
class A() {
|
||||
val a: Int = 0
|
||||
<caret>set(v: Int) {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Replace to dot call" "true"
|
||||
fun foo(a: Any) {
|
||||
<caret>a.equals(0)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Replace to dot call" "true"
|
||||
fun foo(a: Any) {
|
||||
when (a) {
|
||||
.equals(0) => true
|
||||
else => false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Replace a cast with a static assert" "true"
|
||||
fun foo(a: String) {
|
||||
val b = a : Any
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove cast" "true"
|
||||
fun foo(a: Any) {
|
||||
val b = a<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove elvis operator" "true"
|
||||
fun foo(a: String) {
|
||||
val b : String = <caret>a
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Replace to dot call" "true"
|
||||
fun foo(a: Any) {
|
||||
a<caret>?.equals(0)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// "Replace to dot call" "true"
|
||||
fun foo(a: Any) {
|
||||
when (a) {
|
||||
<caret>?.equals(0) => true
|
||||
else => false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Replace a cast with a static assert" "true"
|
||||
fun foo(a: String) {
|
||||
val b = a <caret>as Any
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove cast" "true"
|
||||
fun foo(a: Any) {
|
||||
val b = a <caret>as Any
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove elvis operator" "true"
|
||||
fun foo(a: String) {
|
||||
val b : String = <caret>a ?: "s"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove 'override' modifier" "true"
|
||||
class A() {
|
||||
<caret>fun foo() {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Add 'override' modifier" "true"
|
||||
open class A() {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
class B() : A() {
|
||||
override fun <caret>foo() {}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// "Remove 'override' modifier" "true"
|
||||
class A() {
|
||||
<caret>override fun foo() {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// "Add 'override' modifier" "true"
|
||||
open class A() {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
class B() : A() {
|
||||
fun <caret>foo() {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Change getter type to Int" "true"
|
||||
class A() {
|
||||
val i: Int
|
||||
get(): Int = 1
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Change setter parameter type to Int" "true"
|
||||
class A() {
|
||||
var i: Int = 0
|
||||
set(v: Int) {}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Change getter type to Int" "true"
|
||||
class A() {
|
||||
val i: Int
|
||||
get(): <caret>Any = 1
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// "Change setter parameter type to Int" "true"
|
||||
class A() {
|
||||
var i: Int = 0
|
||||
set(v: <caret>Any) {}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
|
||||
import org.jetbrains.jet.JetTestCaseBase;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class AbstractModifierTest extends LightQuickFixTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doAllTests();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/quickfix/abstract";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JetTestCaseBase.getTestDataPathBase();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
|
||||
import org.jetbrains.jet.JetTestCaseBase;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class ChangeVariableMutabilityTest extends LightQuickFixTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doAllTests();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/quickfix/changeVariableMutability";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JetTestCaseBase.getTestDataPathBase();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
|
||||
import org.jetbrains.jet.JetTestCaseBase;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class ExpressionsTest extends LightQuickFixTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doAllTests();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/quickfix/expressions";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JetTestCaseBase.getTestDataPathBase();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
|
||||
import org.jetbrains.jet.JetTestCaseBase;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class OverrideModifierTest extends LightQuickFixTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doAllTests();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/quickfix/override";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JetTestCaseBase.getTestDataPathBase();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package org.jetbrains.jet.plugin.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
|
||||
import org.jetbrains.jet.JetTestCaseBase;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class TypeAdditionTests extends LightQuickFixTestCase {
|
||||
|
||||
public void test() throws Exception {
|
||||
doAllTests();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/quickfix/typeAddition";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JetTestCaseBase.getTestDataPathBase();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user