Added ModifierFix

This commit is contained in:
svtk
2011-09-19 12:15:47 +04:00
parent 4b720733c0
commit 408c68795d
8 changed files with 206 additions and 167 deletions
@@ -5,7 +5,7 @@ import com.intellij.psi.PsiElement;
/**
* @author svtk
*/
public class PsiElementOnlyDiagnosticFactory2<T extends PsiElement, A, B> extends DiagnosticFactoryWithPsiElement2<T, A, B> implements PsiElementOnlyDiagnosticFactory {
public class PsiElementOnlyDiagnosticFactory2<T extends PsiElement, A, B> extends DiagnosticFactoryWithPsiElement2<T, A, B> implements PsiElementOnlyDiagnosticFactory<T> {
public static <T extends PsiElement, A, B> PsiElementOnlyDiagnosticFactory2<T, A, B> create(Severity severity, String messageStub) {
return new PsiElementOnlyDiagnosticFactory2<T, A, B>(severity, messageStub);
}
@@ -1,21 +1,17 @@
package org.jetbrains.jet.lang.diagnostics;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* @author svtk
*/
public class SimplePsiElementOnlyDiagnosticFactory<T extends PsiElement> extends SimpleDiagnosticFactoryWithPsiElement<T> implements PsiElementOnlyDiagnosticFactory<T> {
public class SimplePsiElementOnlyDiagnosticFactory<T extends PsiElement> extends SimpleDiagnosticFactoryWithPsiElement<T> implements PsiElementOnlyDiagnosticFactory<T> {
public static <T extends PsiElement> SimplePsiElementOnlyDiagnosticFactory<T> create(Severity severity, String message) {
return new SimplePsiElementOnlyDiagnosticFactory<T>(severity, message);
}
public static <T extends PsiElement> SimplePsiElementOnlyDiagnosticFactory<T> create(Severity severity, String message) {
return new SimplePsiElementOnlyDiagnosticFactory<T>(severity, message);
}
protected SimplePsiElementOnlyDiagnosticFactory(Severity severity, String message) {
super(severity, message);
}
protected SimplePsiElementOnlyDiagnosticFactory(Severity severity, String message) {
super(severity, message);
}
}
@@ -1,83 +0,0 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.lang.ASTNode;
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.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lexer.JetTokens;
/**
* @author svtk
*/
public class AddAbstractModifierFix extends IntentionActionForPsiElement<JetModifierListOwner> {
public AddAbstractModifierFix(@NotNull JetModifierListOwner element) {
super(element);
}
@NotNull
@Override
public String getText() {
return "add.abstract.modifier.fix";
}
@NotNull
@Override
public String getFamilyName() {
return "add.abstract.modifier.family";
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return element.isValid() && !element.hasModifier(JetTokens.FINAL_KEYWORD);
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
element.replace(addAbstractModifier(element, project));
}
@NotNull
public static JetModifierListOwner addAbstractModifier(@NotNull PsiElement element, @NotNull Project project) {
JetModifierListOwner newElement = (JetModifierListOwner) (element.copy());
JetModifierList modifierList = newElement.getModifierList();
JetModifierList listWithModifier = JetPsiFactory.createModifier(project, JetTokens.ABSTRACT_KEYWORD);
PsiElement whiteSpace = JetPsiFactory.createWhiteSpace(project);
if (modifierList == null) {
PsiElement firstChild = newElement.getFirstChild();
newElement.addBefore(listWithModifier, firstChild);
newElement.addBefore(whiteSpace, firstChild);
}
else if (modifierList.hasModifier(JetTokens.OPEN_KEYWORD)) {
PsiElement openModifierPsi = modifierList.getModifierNode(JetTokens.OPEN_KEYWORD).getPsi();
assert openModifierPsi != null;
openModifierPsi.replace(listWithModifier.getFirstChild());
}
else {
PsiElement lastChild = modifierList.getLastChild();
modifierList.addAfter(listWithModifier.getFirstChild(), lastChild);
modifierList.addAfter(whiteSpace, lastChild);
}
return newElement;
}
@Override
public boolean startInWriteAction() {
return true;
}
public static IntentionActionFactory<JetModifierListOwner> factory =
new IntentionActionFactory<JetModifierListOwner>() {
@Override
public IntentionActionForPsiElement<JetModifierListOwner> createAction(DiagnosticWithPsiElement diagnostic) {
assert diagnostic.getPsiElement() instanceof JetModifierListOwner;
return new AddAbstractModifierFix((JetModifierListOwner) diagnostic.getPsiElement());
}
};
}
@@ -0,0 +1,97 @@
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.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lexer.JetKeywordToken;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
/**
* @author svtk
*/
public class AddModifierFix extends ModifierFix {
private final JetToken[] modifiersThanCanBeReplaced;
private AddModifierFix(@NotNull JetModifierListOwner element, JetKeywordToken modifier, JetToken[] modifiersThanCanBeReplaced) {
super(element, modifier);
this.modifiersThanCanBeReplaced = modifiersThanCanBeReplaced;
}
@NotNull
@Override
public String getText() {
return "add." + modifier.getValue() + ".modifier.fix";
}
@NotNull
@Override
public String getFamilyName() {
return "add." + modifier.getValue() + ".modifier.family";
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return super.isAvailable(project, editor, file) && !element.hasModifier(JetTokens.FINAL_KEYWORD);
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
element.replace(addModifier(element, modifier, modifiersThanCanBeReplaced, project));
}
@NotNull
private static JetModifierListOwner addModifier(@NotNull PsiElement element, @NotNull JetKeywordToken modifier, JetToken[] modifiersThanCanBeReplaced, @NotNull Project project) {
JetModifierListOwner newElement = (JetModifierListOwner) (element.copy());
JetModifierList modifierList = newElement.getModifierList();
JetModifierList listWithModifier = JetPsiFactory.createModifier(project, modifier);
PsiElement whiteSpace = JetPsiFactory.createWhiteSpace(project);
if (modifierList == null) {
PsiElement firstChild = newElement.getFirstChild();
newElement.addBefore(listWithModifier, firstChild);
newElement.addBefore(whiteSpace, firstChild);
}
else {
boolean replaced = false;
for (JetToken modifierThanCanBeReplaced : modifiersThanCanBeReplaced) {
if (modifierList.hasModifier(modifierThanCanBeReplaced)) {
PsiElement openModifierPsi = modifierList.getModifierNode(modifierThanCanBeReplaced).getPsi();
assert openModifierPsi != null;
openModifierPsi.replace(listWithModifier.getFirstChild());
replaced = true;
}
}
if (!replaced) {
PsiElement lastChild = modifierList.getLastChild();
modifierList.addAfter(listWithModifier.getFirstChild(), lastChild);
modifierList.addAfter(whiteSpace, lastChild);
}
}
return newElement;
}
@Override
public boolean startInWriteAction() {
return true;
}
public static IntentionActionFactory<JetModifierListOwner> createFactory(final JetKeywordToken modifier, final JetToken[] modifiersThatCanBeReplaced) {
return new IntentionActionFactory<JetModifierListOwner>() {
@Override
public IntentionActionForPsiElement<JetModifierListOwner> createAction(DiagnosticWithPsiElement diagnostic) {
assert diagnostic.getPsiElement() instanceof JetModifierListOwner;
return new AddModifierFix((JetModifierListOwner) diagnostic.getPsiElement(), modifier, modifiersThatCanBeReplaced);
}
};
}
public static IntentionActionFactory<JetModifierListOwner> createFactory(final JetKeywordToken modifier) {
return createFactory(modifier, new JetToken[] {});
}
}
@@ -0,0 +1,31 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
import org.jetbrains.jet.lexer.JetKeywordToken;
/**
* @author svtk
*/
public abstract class ModifierFix extends IntentionActionForPsiElement<JetModifierListOwner> {
protected final JetKeywordToken modifier;
protected ModifierFix(@NotNull JetModifierListOwner element, JetKeywordToken modifier) {
super(element);
this.modifier = modifier;
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return element.isValid();
}
@Override
public boolean startInWriteAction() {
return true;
}
}
@@ -1,10 +1,12 @@
package org.jetbrains.jet.plugin.quickfix;
import com.google.common.collect.Maps;
import com.intellij.codeInsight.intention.IntentionAction;
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.JetModifierListOwner;
import org.jetbrains.jet.lexer.JetToken;
import org.jetbrains.jet.lexer.JetTokens;
import java.util.Map;
@@ -26,9 +28,12 @@ public class QuickFixes {
static {
add(Errors.REDUNDANT_ABSTRACT, RemoveAbstractModifierFix.factory);
add(Errors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, RemoveAbstractModifierFix.factory);
add(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, AddAbstractModifierFix.factory);
IntentionActionFactory<JetModifierListOwner> removeAbstractModifierFactory = RemoveModifierFix.createFactory(JetTokens.ABSTRACT_KEYWORD);
IntentionActionFactory<JetModifierListOwner> addAbstractModifierFactory = AddModifierFix.createFactory(JetTokens.ABSTRACT_KEYWORD, new JetToken[]{JetTokens.OPEN_KEYWORD});
add(Errors.REDUNDANT_ABSTRACT, removeAbstractModifierFactory);
add(Errors.ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, removeAbstractModifierFactory);
add(Errors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY, addAbstractModifierFactory);
}
}
@@ -1,68 +0,0 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.lang.ASTNode;
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.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
import org.jetbrains.jet.lexer.JetTokens;
/**
* @author svtk
*/
public class RemoveAbstractModifierFix extends IntentionActionForPsiElement<JetModifierListOwner> {
public RemoveAbstractModifierFix(@NotNull JetModifierListOwner element) {
super(element);
}
@NotNull
@Override
public String getText() {
return "remove.abstract.modifier.fix";
}
@NotNull
@Override
public String getFamilyName() {
return "remove.abstract.modifier.family";
}
@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 {
element.replace(removeAbstractModifier(element));
}
@NotNull
public static JetModifierListOwner removeAbstractModifier(PsiElement element) {
JetModifierListOwner newElement = (JetModifierListOwner) (element.copy());
assert newElement.hasModifier(JetTokens.ABSTRACT_KEYWORD);
ASTNode abstractNode = newElement.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD);
((JetElement)newElement).deleteChildInternal(abstractNode);
return newElement;
}
@Override
public boolean startInWriteAction() {
return true;
}
public static IntentionActionFactory<JetModifierListOwner> factory =
new IntentionActionFactory<JetModifierListOwner>() {
@Override
public IntentionActionForPsiElement<JetModifierListOwner> createAction(DiagnosticWithPsiElement diagnostic) {
assert diagnostic.getPsiElement() instanceof JetModifierListOwner;
return new RemoveAbstractModifierFix((JetModifierListOwner) diagnostic.getPsiElement());
}
};
}
@@ -0,0 +1,61 @@
package org.jetbrains.jet.plugin.quickfix;
import com.intellij.lang.ASTNode;
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.DiagnosticWithPsiElement;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
import org.jetbrains.jet.lexer.JetKeywordToken;
import org.jetbrains.jet.lexer.JetToken;
/**
* @author svtk
*/
public class RemoveModifierFix extends ModifierFix {
public RemoveModifierFix(@NotNull JetModifierListOwner element, JetKeywordToken modifier) {
super(element, modifier);
}
@NotNull
@Override
public String getText() {
return "remove." + modifier.getValue() + ".modifier.fix";
}
@NotNull
@Override
public String getFamilyName() {
return "remove." + modifier.getValue() + "abstract.modifier.family";
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
element.replace(removeModifier(element, modifier));
}
@NotNull
private static JetModifierListOwner removeModifier(PsiElement element, JetToken modifier) {
JetModifierListOwner newElement = (JetModifierListOwner) (element.copy());
assert newElement.hasModifier(modifier);
ASTNode modifierNode = newElement.getModifierList().getModifierNode(modifier);
((JetElement)newElement).deleteChildInternal(modifierNode);
return newElement;
}
public static IntentionActionFactory<JetModifierListOwner> createFactory(final JetKeywordToken modifier) {
return new IntentionActionFactory<JetModifierListOwner>() {
@Override
public IntentionActionForPsiElement<JetModifierListOwner> createAction(DiagnosticWithPsiElement diagnostic) {
assert diagnostic.getPsiElement() instanceof JetModifierListOwner;
return new RemoveModifierFix((JetModifierListOwner) diagnostic.getPsiElement(), modifier);
}
};
}
}