package de.plushnikov.intellij.plugin.quickfix; import com.intellij.codeInsight.CodeInsightUtil; import com.intellij.codeInsight.generation.GenerateMembersUtil; import com.intellij.codeInsight.generation.PsiGenerationInfo; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.application.Result; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.command.undo.UndoUtil; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElementFactory; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiField; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiModifierList; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; /** * @author Plushnikov Michail */ public class CreateFieldQuickFix implements IntentionAction, LocalQuickFix { private final PsiClass myClass; private final String myName; private final PsiType myType; private final String myInitializerText; private final Collection<String> myModifiers; public CreateFieldQuickFix(@NotNull PsiClass psiClass, @NotNull String name, @NotNull PsiType psiType, @Nullable String initializerText, String... modifiers) { myClass = psiClass; myName = name; myType = psiType; myInitializerText = initializerText; myModifiers = Arrays.asList(modifiers); } @NotNull public String getText() { return String.format("Create new field '%s'", myName); } @NotNull public String getName() { return getText(); } @NotNull public String getFamilyName() { return getText(); } public void applyFix(@NotNull final Project project, @NotNull ProblemDescriptor descriptor) { applyFixInner(project); } public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { return true; } public void invoke(@NotNull Project project, Editor editor, PsiFile file) { applyFixInner(project); } private void applyFixInner(final Project project) { final PsiFile psiFile = myClass.getContainingFile(); final Editor editor = CodeInsightUtil.positionCursor(project, psiFile, myClass.getLBrace()); if (editor != null) { new WriteCommandAction(project, psiFile) { protected void run(@NotNull Result result) throws Throwable { final PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(myClass.getProject()); final PsiField psiField = psiElementFactory.createField(myName, myType); final PsiModifierList modifierList = psiField.getModifierList(); if (null != modifierList) { for (String modifier : myModifiers) { modifierList.setModifierProperty(modifier, true); } } if (null != myInitializerText) { PsiExpression psiInitializer = psiElementFactory.createExpressionFromText(myInitializerText, psiField); psiField.setInitializer(psiInitializer); } final List<PsiGenerationInfo<PsiField>> generationInfos = GenerateMembersUtil.insertMembersAtOffset(myClass.getContainingFile(), editor.getCaretModel().getOffset(), Collections.singletonList(new PsiGenerationInfo<PsiField>(psiField))); if (!generationInfos.isEmpty()) { PsiField psiMember = generationInfos.iterator().next().getPsiMember(); editor.getCaretModel().moveToOffset(psiMember.getTextRange().getEndOffset()); } UndoUtil.markPsiFileForUndo(psiFile); } @Override protected boolean isGlobalUndoAction() { return true; } }.execute(); } } public boolean startInWriteAction() { return false; } }